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
+