[svn:parrot] r49150 - in trunk: include/parrot src/pmc t/pmc
luben at svn.parrot.org
luben at svn.parrot.org
Sun Sep 19 06:57:55 UTC 2010
Author: luben
Date: Sun Sep 19 06:57:54 2010
New Revision: 49150
URL: https://trac.parrot.org/parrot/changeset/49150
Log:
reworked HashIterator PMC to use linear scan
- removed unused macro
- unTODO-ed some tests that check hash internals
Modified:
trunk/include/parrot/hash.h
trunk/src/pmc/hashiterator.pmc
trunk/t/pmc/hash.t
Modified: trunk/include/parrot/hash.h
==============================================================================
--- trunk/include/parrot/hash.h Sun Sep 19 04:38:26 2010 (r49149)
+++ trunk/include/parrot/hash.h Sun Sep 19 06:57:54 2010 (r49150)
@@ -90,33 +90,17 @@
#define parrot_hash_iterate_indexed(_hash, _code) \
{ \
INTVAL _loc; \
- if ((_hash)->entries){ \
- for (_loc = 0; _loc <= (_hash)->mask; ++_loc) { \
- HashBucket *_bucket = (_hash)->index[_loc]; \
- while (_bucket) { \
- _code \
- _bucket = _bucket->next; \
- } \
+ if ((_hash)->entries){ \
+ for (_loc = 0; _loc <= (_hash)->mask; ++_loc) { \
+ HashBucket *_bucket = (_hash)->index[_loc]; \
+ while (_bucket) { \
+ _code \
+ _bucket = _bucket->next; \
} \
} \
-}
-
-#define parrot_hash_iterator_advance(_hash, _bucket, _loc) \
-{ \
- if ((_hash)->entries) { \
- /* Try to advance current bucket */ \
- if ((_bucket)) \
- (_bucket) = (_bucket)->next; \
- while (!(_bucket)) { \
- /* If there is no more buckets */ \
- if ((_loc) == (INTVAL)(_hash)->mask+1) \
- break; \
- (_bucket) = (_hash)->index[(_loc)++]; \
- } \
} \
}
-
typedef void (*value_free)(ARGFREE(void *));
/* To avoid creating OrderedHashItem PMC we reuse FixedPMCArray PMC */
Modified: trunk/src/pmc/hashiterator.pmc
==============================================================================
--- trunk/src/pmc/hashiterator.pmc Sun Sep 19 04:38:26 2010 (r49149)
+++ trunk/src/pmc/hashiterator.pmc Sun Sep 19 06:57:54 2010 (r49150)
@@ -79,7 +79,13 @@
{
ASSERT_ARGS(advance_to_next)
Parrot_HashIterator_attributes * const attrs = PARROT_HASHITERATOR(self);
- parrot_hash_iterator_advance(attrs->parrot_hash, attrs->bucket, attrs->pos);
+
+ while(attrs->elements > 0){
+ attrs->bucket = attrs->parrot_hash->buckets + attrs->pos++;
+ if (attrs->bucket->key){
+ break;
+ }
+ }
--attrs->elements;
return;
}
@@ -110,17 +116,11 @@
attrs->pmc_hash = hash;
attrs->parrot_hash = (Hash*)VTABLE_get_pointer(INTERP, hash);
attrs->total_buckets = attrs->parrot_hash->mask + 1;
- attrs->bucket = 0;
+ attrs->bucket = attrs->parrot_hash->buckets;
+ attrs->elements = attrs->parrot_hash->entries;
attrs->pos = 0;
- /* Will be decreased on initial advance_to_next */
- /* XXX Do we really need to support this use-case ? */
- attrs->elements = attrs->parrot_hash->entries + 1;
PObj_custom_mark_SET(SELF);
-
- /* Initial state of iterator is "before start" */
- /* So, advance to first element */
- advance_to_next(INTERP, SELF);
}
/*
@@ -163,9 +163,9 @@
if (value == ITERATE_FROM_START) {
/* Restart iterator */
- attrs->bucket = 0;
+ attrs->bucket = attrs->parrot_hash->buckets;
+ attrs->elements = attrs->parrot_hash->entries;
attrs->pos = 0;
- advance_to_next(INTERP, SELF);
return;
}
@@ -197,7 +197,8 @@
*/
VTABLE INTVAL get_bool() {
- return PARROT_HASHITERATOR(SELF)->bucket != 0;
+ return PARROT_HASHITERATOR(SELF)->elements != 0;
+
}
/*
@@ -215,7 +216,7 @@
}
VTABLE INTVAL get_integer() {
- return SELF.elements();
+ return PARROT_HASHITERATOR(SELF)->elements;
}
/*
@@ -235,7 +236,10 @@
PMC *ret;
- if (!attrs->bucket)
+ /* Move to next bucket */
+ advance_to_next(INTERP, SELF);
+
+ if (attrs->elements < 0)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"StopIteration");
@@ -243,9 +247,6 @@
VTABLE_set_pointer_keyed_int(INTERP, ret, 0, attrs->parrot_hash);
VTABLE_set_pointer_keyed_int(INTERP, ret, 1, attrs->bucket);
- /* Move to next bucket */
- advance_to_next(INTERP, SELF);
-
return ret;
}
@@ -254,17 +255,15 @@
*/
VTABLE STRING* shift_string() {
- Parrot_HashIterator_attributes * const attrs =
- PARROT_HASHITERATOR(SELF);
- HashBucket * const bucket = attrs->bucket;
-
- if (!attrs->parrot_hash || !attrs->bucket)
- return CONST_STRING(INTERP, "");
+ Parrot_HashIterator_attributes * const attrs = PARROT_HASHITERATOR(SELF);
/* Move to next bucket */
advance_to_next(INTERP, SELF);
- return hash_key_to_string(INTERP, attrs->parrot_hash, bucket->key);
+ if (attrs->elements < 0)
+ return CONST_STRING(INTERP, "");
+
+ return hash_key_to_string(INTERP, attrs->parrot_hash, attrs->bucket->key);
}
}
Modified: trunk/t/pmc/hash.t
==============================================================================
--- trunk/t/pmc/hash.t Sun Sep 19 04:38:26 2010 (r49149)
+++ trunk/t/pmc/hash.t Sun Sep 19 06:57:54 2010 (r49150)
@@ -663,9 +663,6 @@
# To try to ensure that the test fails reliably if there's a regression, it's
# run 3 times with different hash keys.
.sub clone_preserves_order
- todo("clone preserves hash internal order")
- .return ()
-
.local pmc h, cloned
.local string s1, s2
.local int all_ok
@@ -742,10 +739,6 @@
.end
.sub freeze_thaw_preserves_order
- # is internal order important somehow?
- todo("freeze/thaw preserves hash internal order")
- .return ()
-
.local pmc h, cloned
.local string s1, s2
.local int all_ok
More information about the parrot-commits
mailing list