[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