Author: leo
Date: Thu Jan 12 03:21:43 2006
New Revision: 11121

Modified:
   trunk/src/classes/orderedhash.pmc
   trunk/t/pmc/orderedhash.t
Log:
OrderedHash - compound keys

* implement compound keys in OrderedHash 
* test set, get, exists, delete w string and int compound keys


Modified: trunk/src/classes/orderedhash.pmc
==============================================================================
--- trunk/src/classes/orderedhash.pmc   (original)
+++ trunk/src/classes/orderedhash.pmc   Thu Jan 12 03:21:43 2006
@@ -79,11 +79,16 @@ pmclass OrderedHash extends Hash need_ex
     }
 
     PMC* get_pmc_keyed (PMC* key) {
+        PMC *item, *next;
         switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
             case KEY_hash_iterator_FLAGS:
                 return SUPER(key);
             case KEY_integer_FLAG:
-                return SELF.get_pmc_keyed_int(key_integer(INTERP, key));
+                item = SELF.get_pmc_keyed_int(key_integer(INTERP, key));
+                next = key_next(INTERP, key);
+                if (!next)
+                    return item;
+                return VTABLE_get_pmc_keyed(INTERP, item, next);
             default:
                 return SUPER(key);
         }
@@ -122,11 +127,16 @@ pmclass OrderedHash extends Hash need_ex
     }
 
     STRING* get_string_keyed (PMC* key) {
+        PMC *item, *next;
         switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
             case KEY_hash_iterator_FLAGS:
                 return SUPER(key);
             case KEY_integer_FLAG:
-                return SELF.get_string_keyed_int(key_integer(INTERP, key));
+                item = SELF.get_pmc_keyed_int(key_integer(INTERP, key));
+                next = key_next(INTERP, key);
+                if (!next)
+                    return VTABLE_get_string(INTERP, item);
+                return VTABLE_get_string_keyed(INTERP, item, next);
             default:
                 return SUPER(key);
         }
@@ -167,11 +177,16 @@ Returns the integer value associated wit
     }
 
     INTVAL get_integer_keyed (PMC* key) {
+        PMC *item, *next;
         switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
             case KEY_hash_iterator_FLAGS:
                 return SUPER(key);
             case KEY_integer_FLAG:
-                return SELF.get_integer_keyed_int(key_integer(INTERP, key));
+                item = SELF.get_pmc_keyed_int(key_integer(INTERP, key));
+                next = key_next(INTERP, key);
+                if (!next)
+                    return VTABLE_get_integer(INTERP, item);
+                return VTABLE_get_integer_keyed(INTERP, item, next);
             default:
                 return SUPER(key);
         }
@@ -212,11 +227,16 @@ Returns the floating-point value for the
     }
 
     FLOATVAL get_number_keyed (PMC* key) {
+        PMC *item, *next;
         switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
             case KEY_hash_iterator_FLAGS:
                 return SUPER(key);
             case KEY_integer_FLAG:
-                return SELF.get_number_keyed_int(key_integer(INTERP, key));
+                item = SELF.get_pmc_keyed_int(key_integer(INTERP, key));
+                next = key_next(INTERP, key);
+                if (!next)
+                    return VTABLE_get_number(INTERP, item);
+                return VTABLE_get_number_keyed(INTERP, item, next);
             default:
                 return SUPER(key);
         }
@@ -347,13 +367,32 @@ The created key = "\1idx".
             return 1;
         return 0;
     }
+
     INTVAL exists_keyed(PMC* key) {
+        PMC *item, *next;
         if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
-            return SELF.exists_keyed_int(key_integer(INTERP, key));
+            Hash *h = PMC_struct_val(SELF);
+            INTVAL n, idx;
+            HashBucket *b;
+
+            idx = key_integer(INTERP, key);
+            n = h->entries;
+            if (idx < 0)
+                idx += n;
+            if (idx < 0 || idx >= n) {
+                return 0;
+            }
+            b = h->bs + idx;
+            if (!b->key)
+                return 0;
+            item = b->value;
+            next = key_next(INTERP, key);
+            if (!next)
+                return 1;
+            return VTABLE_exists_keyed(INTERP, item, next);
         }
         else {
-            /* TODO handle composite keys */
-            return SELF.exists_keyed_str(key_string(INTERP, key));
+            return SUPER(key);
         }
     }
 
@@ -380,8 +419,28 @@ The created key = "\1idx".
 
 
     INTVAL defined_keyed(PMC *key) {
+        PMC *item, *next;
         if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
-            return SELF.defined_keyed_int(key_integer(INTERP, key));
+            Hash *h = PMC_struct_val(SELF);
+            INTVAL n, idx;
+            HashBucket *b;
+
+            idx = key_integer(INTERP, key);
+            n = h->entries;
+            if (idx < 0)
+                idx += n;
+            if (idx < 0 || idx >= n) {
+                /* XXX non-existant is undefined - is this correct */
+                return 0;
+            }
+            b = h->bs + idx;
+            if (!b->key)
+                return 0;
+            item = b->value;
+            next = key_next(INTERP, key);
+            if (!next)
+                return VTABLE_defined(INTERP, item);
+            return VTABLE_defined_keyed(INTERP, item, next);
         }
         return SUPER(key);
     }
@@ -418,11 +477,22 @@ Deletes the key C<*key> from the hash.
 */
 
     void delete_keyed(PMC* key) {
+        PMC *item, *next;
+        next = key_next(INTERP, key);
         if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
+            if (next) {
+                item = SELF.get_pmc_keyed_int(key_integer(INTERP, key));
+                VTABLE_delete_keyed(INTERP, item, next);
+                return;
+            }
             SELF.delete_keyed_int(key_integer(INTERP, key));
         }
         else {
-            /* TODO handle composite keys */
+            if (next) {
+                item = DYNSELF.get_pmc_keyed_str(key_string(INTERP, key));
+                VTABLE_delete_keyed(INTERP, item, next);
+                return;
+            }
             SELF.delete_keyed_str(key_string(INTERP, key));
         }
     }

Modified: trunk/t/pmc/orderedhash.t
==============================================================================
--- trunk/t/pmc/orderedhash.t   (original)
+++ trunk/t/pmc/orderedhash.t   Thu Jan 12 03:21:43 2006
@@ -6,7 +6,7 @@ use strict;
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 22;
+use Parrot::Test tests => 25;
 
 =head1 NAME
 
@@ -638,3 +638,117 @@ ok 2
 ok 3
 ok 4
 OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "set/get compound key");
+    new P0, .OrderedHash
+    set P0["a"], "Foo\n"
+    new P1, .Hash
+    set P1['foo'], "bar\n"
+    set P0["b"], P1
+    set P2, P0['b'; 'foo']
+    print P2
+    set P0['b'; 'foo'], "baz\n"
+    set P0['b'; 'quux'], "xyzzy\n"
+    set P2, P0['b'; 'foo']
+    print P2
+    set P2, P0['b'; 'quux']
+    print P2
+    print "--\n"
+    set P2, P0[0] 
+    print P2
+    set P2, P0[1, 'foo'] 
+    print P2
+    set P2, P0[1, 'quux'] 
+    print P2
+    end
+CODE
+bar
+baz
+xyzzy
+--
+Foo
+baz
+xyzzy
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "exists compound key");
+    new P0, .OrderedHash
+    set P0["a"], "Foo"
+    new P1, .Hash
+    set P1['foo'], "bar\n"
+    set P0["b"], P1
+    set P0['b'; 'quux'], "xyzzy\n"
+    exists I0, P0['a']
+    print I0
+    exists I0, P0['b'; 'foo']
+    print I0
+    exists I0, P0['b'; 'quux']
+    print I0
+    exists I0, P0['b'; 'nada']
+    print I0
+    exists I0, P0['c']
+    print I0
+    print "\n--\n"
+    exists I0, P0[0]
+    print I0
+    exists I0, P0[1; 'foo']
+    print I0
+    exists I0, P0[1; 'quux']
+    print I0
+    exists I0, P0[1; 'nada']
+    print I0
+    exists I0, P0[2]
+    print I0
+    print "\n"
+    end
+CODE
+11100
+--
+11100
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "delete compound key");
+    new P0, .OrderedHash
+    set P0["a"], "Foo"
+    new P1, .Hash
+    set P1['foo'], "bar\n"
+    set P0["b"], P1
+    set P0['b'; 'quux'], "xyzzy\n"
+    delete  P0['b'; 'foo']
+    exists I0, P0['a']
+    print I0
+    exists I0, P0['b'; 'foo']
+    print I0
+    exists I0, P0['b'; 'quux']
+    print I0
+    exists I0, P0['b'; 'nada']
+    print I0
+    exists I0, P0['c']
+    print I0
+    print "\n--\n"
+    exists I0, P0[0]
+    print I0
+    exists I0, P0[1; 'foo']
+    print I0
+    exists I0, P0[1; 'quux']
+    print I0
+    exists I0, P0[1; 'nada']
+    print I0
+    exists I0, P0[2]
+    print I0
+    print "\n--\n"
+    delete P0[1, 'quux']
+    exists I0, P0['b'; 'quux']
+    print I0
+    exists I0, P0[1; 'quux']
+    print I0
+    print "\n"
+    end
+CODE
+10100
+--
+10100
+--
+00
+OUTPUT
+

Reply via email to