[svn:parrot] r40238 - branches/orderedhash_revamp/src/pmc

bacek at svn.parrot.org bacek at svn.parrot.org
Thu Jul 23 23:06:05 UTC 2009


Author: bacek
Date: Thu Jul 23 23:06:04 2009
New Revision: 40238
URL: https://trac.parrot.org/parrot/changeset/40238

Log:
[pmc] Implement basic iteration over OrderedHash

Modified:
   branches/orderedhash_revamp/src/pmc/orderedhashiterator.pmc

Modified: branches/orderedhash_revamp/src/pmc/orderedhashiterator.pmc
==============================================================================
--- branches/orderedhash_revamp/src/pmc/orderedhashiterator.pmc	Thu Jul 23 23:04:16 2009	(r40237)
+++ branches/orderedhash_revamp/src/pmc/orderedhashiterator.pmc	Thu Jul 23 23:06:04 2009	(r40238)
@@ -18,12 +18,12 @@
 
 */
 
-#include "pmc_hash.h"
+#include "pmc_orderedhash.h"
 #include "pmc_hashiteratorkey.h"
 
 pmclass OrderedHashIterator extends Iterator no_ro {
     ATTR PMC        *pmc_hash;      /* the Hash which this Iterator iterates */
-    ATTR Hash       *parrot_hash;   /* Underlying implementation of hash */
+    ATTR PMC        *next_entry;    /* Next entry to shift/pop */
     ATTR INTVAL      pos;           /* */
     ATTR INTVAL      elements;      /* How many elements left to iterate over */
     ATTR INTVAL      reverse;       /* Direction of iteration. 1 - for reverse iteration */
@@ -44,11 +44,9 @@
             mem_allocate_zeroed_typed(Parrot_OrderedHashIterator_attributes);
 
         attrs->pmc_hash         = hash;
-        attrs->parrot_hash      = (Hash*)VTABLE_get_pointer(INTERP, hash);
         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;
+        attrs->elements         = VTABLE_elements(INTERP, hash);
+        attrs->next_entry       = PARROT_ORDEREDHASH(hash)->first;
         PMC_data(SELF)          = attrs;
 
         PObj_custom_mark_destroy_SETALL(SELF);
@@ -107,15 +105,17 @@
                 PARROT_ORDEREDHASHITERATOR(SELF);
 
         /* Restart iterator */
-        attrs->elements         = attrs->parrot_hash->entries;
+        attrs->elements = VTABLE_elements(INTERP, attrs->pmc_hash);
         if (value == ITERATE_FROM_START || value == ITERATE_FROM_START_KEYS) {
-            attrs->pos      = 0;
-            attrs->reverse  = 0;
+            attrs->pos          = 0;
+            attrs->reverse      = 0;
+            attrs->next_entry   = PARROT_ORDEREDHASH(attrs->pmc_hash)->first;
             return;
         }
         else if (value == ITERATE_FROM_END) {
-            attrs->pos      = attrs->elements;
-            attrs->reverse  = 1;
+            attrs->pos          = attrs->elements;
+            attrs->reverse      = 1;
+            attrs->next_entry   = PARROT_ORDEREDHASH(attrs->pmc_hash)->last;
             return;
         }
 
@@ -183,23 +183,18 @@
                 PARROT_ORDEREDHASHITERATOR(SELF);
 
         PMC        *ret;
-        HashBucket *bucket;
 
         if (!attrs->elements)
             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
                 "StopIteration");
 
         /* Get bucket and move to next bucket */
-        do {
-            bucket = attrs->parrot_hash->bs + attrs->pos++;
-            attrs->elements--;
-        } while (attrs->elements && !bucket->key);
-
-        /* Reuse HashIteratorKey */
-        ret = pmc_new(INTERP, enum_class_HashIteratorKey);
-        /* Poke directly into HIK. We don't want to create any kind of public API for this */
-        PARROT_HASHITERATORKEY(ret)->parrot_hash = attrs->parrot_hash;
-        PARROT_HASHITERATORKEY(ret)->bucket      = bucket;
+        ret               = VTABLE_get_pmc_keyed_int(INTERP, attrs->next_entry,
+                ORDERED_HASH_ITEM_KEY);
+        attrs->next_entry = VTABLE_get_pmc_keyed_int(INTERP, attrs->next_entry,
+                ORDERED_HASH_ITEM_NEXT);
+        attrs->pos++;
+        attrs->elements--;
 
         return ret;
     }
@@ -220,22 +215,18 @@
                 PARROT_ORDEREDHASHITERATOR(SELF);
 
         PMC        *ret;
-        HashBucket *bucket;
 
         if (!attrs->elements)
             Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
                 "StopIteration");
 
-        /* Get bucket and move to next bucket */
-        bucket = attrs->parrot_hash->bs + --attrs->pos;
+        ret               = VTABLE_get_pmc_keyed_int(INTERP, attrs->next_entry,
+                ORDERED_HASH_ITEM_KEY);
+        attrs->next_entry = VTABLE_get_pmc_keyed_int(INTERP, attrs->next_entry,
+                ORDERED_HASH_ITEM_PREV);
+        attrs->pos--;
         attrs->elements--;
 
-        /* Reuse HashIteratorKey */
-        ret = pmc_new(INTERP, enum_class_HashIteratorKey);
-        /* Poke directly into HIK. We don't want to create any kind of public API for this */
-        PARROT_HASHITERATORKEY(ret)->parrot_hash = attrs->parrot_hash;
-        PARROT_HASHITERATORKEY(ret)->bucket      = bucket;
-
         return ret;
     }
 


More information about the parrot-commits mailing list