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

bacek at svn.parrot.org bacek at svn.parrot.org
Fri Jul 24 10:33:34 UTC 2009


Author: bacek
Date: Fri Jul 24 10:33:33 2009
New Revision: 40254
URL: https://trac.parrot.org/parrot/changeset/40254

Log:
[pmc] Implement OrderedHash.delete_keyed

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

Modified: branches/orderedhash_revamp/src/pmc/orderedhash.pmc
==============================================================================
--- branches/orderedhash_revamp/src/pmc/orderedhash.pmc	Fri Jul 24 10:33:10 2009	(r40253)
+++ branches/orderedhash_revamp/src/pmc/orderedhash.pmc	Fri Jul 24 10:33:33 2009	(r40254)
@@ -88,6 +88,26 @@
     return ret;
 };
 
+/* Get list_item by index */
+static PMC*
+get_list_item(PARROT_INTERP, ARGIN(PMC *self), INTVAL idx) {
+    Parrot_OrderedHash_attributes *attrs = PARROT_ORDEREDHASH(self);
+    INTVAL                         n = VTABLE_elements(interp, attrs->hash);
+    INTVAL                         pos;
+    PMC                           *list_entry = attrs->first;
+
+    if (idx < -n)
+        idx = -idx - n - 1;
+    else if (idx < 0)
+        idx += n;
+
+    /* Iterate over linked list to get list_item */
+    for (pos = 0; pos < idx; ++pos) {
+        list_entry = VTABLE_get_pmc_keyed_int(interp, list_entry, ORDERED_HASH_ITEM_NEXT);
+    }
+    return list_entry;
+}
+
 /* Find first/last in cloned/thawed OrderedHash */
 /* Parameter C<pmc_hash> is Hash, not OrderedHash */
 static void
@@ -133,7 +153,7 @@
 }
 
 
-pmclass OrderedHash need_ext provides array {
+pmclass OrderedHash need_ext provides array provides hash {
     ATTR PMC    *hash;   /* key to item tuple */
     ATTR PMC    *first;  /* Pointer to first inserted value  */
     ATTR PMC    *last;   /* Pointer to last inserted value   */
@@ -341,20 +361,7 @@
 */
 
     VTABLE PMC *get_pmc_keyed_int(INTVAL idx) {
-        Parrot_OrderedHash_attributes *attrs = PARROT_ORDEREDHASH(SELF);
-        INTVAL                         n = STATICSELF.elements();
-        INTVAL                         pos;
-        PMC                           *list_entry = attrs->first;
-
-        if (idx < -n)
-            idx = -idx - n - 1;
-        else if (idx < 0)
-            idx += n;
-
-        /* Iterate over linked list to get value */
-        for (pos = 0; pos < idx; ++pos) {
-            list_entry = VTABLE_get_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_NEXT);
-        }
+        PMC *list_entry = get_list_item(INTERP, SELF, idx);
 
         if (PMC_IS_NULL(list_entry))
             return PMCNULL;
@@ -488,10 +495,7 @@
             SELF.set_pmc_keyed_str(key, val);
         }
         else {
-            /* Iterate over linked list to get value */
-            for (pos = 0; pos < idx; ++pos) {
-                list_entry = VTABLE_get_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_NEXT);
-            }
+            list_entry = get_list_item(INTERP, SELF, idx);
             PARROT_ASSERT(!PMC_IS_NULL(list_entry));
             VTABLE_set_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_VALUE, val);
         }
@@ -653,15 +657,54 @@
 */
 
     VTABLE void delete_keyed(PMC *key) {
+        Parrot_OrderedHash_attributes *attrs =
+                PARROT_ORDEREDHASH(SELF);
+        PMC *list_entry, *prev, *next;
+        if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
+            INTVAL    intval = VTABLE_get_integer(INTERP, key);
+            PMC * const next = VTABLE_shift_pmc(INTERP, key);
+
+            if (!next)
+                return STATICSELF.delete_keyed_int(intval);
+
+            return VTABLE_delete_keyed(INTERP, STATICSELF.get_pmc_keyed_int(intval), next);
+        }
+
+        list_entry = VTABLE_get_pmc_keyed(INTERP, attrs->hash, key);
+        if (PMC_IS_NULL(list_entry))
+            return;
+
+        /* Unlink entry */
+        next = VTABLE_get_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_NEXT);
+        prev = VTABLE_get_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_PREV);
+
+        if (attrs->first == list_entry)
+            attrs->first = next;
+
+        if (attrs->last == list_entry)
+            attrs->last = prev;
+
+        /* C<prev> and C<next> are list entries (FPA) */
+        if (!PMC_IS_NULL(prev))
+            VTABLE_set_pmc_keyed_int(INTERP, prev, ORDERED_HASH_ITEM_NEXT, next);
+        if (!PMC_IS_NULL(next))
+            VTABLE_set_pmc_keyed_int(INTERP, next, ORDERED_HASH_ITEM_PREV, prev);
+
+        /* And finally delete it */
         return VTABLE_delete_keyed(INTERP, PARROT_ORDEREDHASH(SELF)->hash, key);
     }
 
     VTABLE void delete_keyed_str(STRING *key) {
-        return VTABLE_delete_keyed_str(INTERP, PARROT_ORDEREDHASH(SELF)->hash, key);
+        return STATICSELF.delete_keyed(box_string(INTERP, key));
     }
 
     VTABLE void delete_keyed_int(INTVAL idx) {
-        PARROT_ASSERT(!"Bah");
+        PMC *list_entry;
+        if (!STATICSELF.exists_keyed_int(idx))
+            return;
+
+        list_entry = get_list_item(INTERP, SELF, idx);
+        STATICSELF.delete_keyed(VTABLE_get_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_KEY));
     }
 
 /*


More information about the parrot-commits mailing list