Reimplement some Hash methods without iterators Creating a HashIterator object in Hash#Keys, Hash#Values, and Hash#Equals would be even more expensive. Switch to a direct approach.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/adf06650 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/adf06650 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/adf06650 Branch: refs/heads/master Commit: adf06650f99f3822e7f3a08922800706ff6b8a5a Parents: 0b27c67 Author: Nick Wellnhofer <[email protected]> Authored: Thu Apr 16 21:44:55 2015 +0200 Committer: Nick Wellnhofer <[email protected]> Committed: Thu Apr 16 21:44:55 2015 +0200 ---------------------------------------------------------------------- runtime/core/Clownfish/Hash.c | 46 ++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/adf06650/runtime/core/Clownfish/Hash.c ---------------------------------------------------------------------- diff --git a/runtime/core/Clownfish/Hash.c b/runtime/core/Clownfish/Hash.c index 9f6cbe7..e05a299 100644 --- a/runtime/core/Clownfish/Hash.c +++ b/runtime/core/Clownfish/Hash.c @@ -269,40 +269,52 @@ Hash_Find_Key_IMP(Hash *self, String *key, int32_t hash_sum) { VArray* Hash_Keys_IMP(Hash *self) { - String *key; - Obj *val; - VArray *keys = VA_new(self->size); - Hash_Iterate(self); - while (Hash_Next(self, &key, &val)) { - VA_Push(keys, INCREF(key)); + VArray *keys = VA_new(self->size); + HashEntry *entry = (HashEntry*)self->entries; + HashEntry *const limit = entry + self->capacity; + + for (; entry < limit; entry++) { + if (entry->key && entry->key != TOMBSTONE) { + VA_Push(keys, INCREF(entry->key)); + } } + return keys; } VArray* Hash_Values_IMP(Hash *self) { - String *key; - Obj *val; - VArray *values = VA_new(self->size); - Hash_Iterate(self); - while (Hash_Next(self, &key, &val)) { VA_Push(values, INCREF(val)); } + VArray *values = VA_new(self->size); + HashEntry *entry = (HashEntry*)self->entries; + HashEntry *const limit = entry + self->capacity; + + for (; entry < limit; entry++) { + if (entry->key && entry->key != TOMBSTONE) { + VA_Push(values, INCREF(entry->value)); + } + } + return values; } bool Hash_Equals_IMP(Hash *self, Obj *other) { Hash *twin = (Hash*)other; - String *key; - Obj *val; if (twin == self) { return true; } if (!Obj_Is_A(other, HASH)) { return false; } if (self->size != twin->size) { return false; } - Hash_Iterate(self); - while (Hash_Next(self, &key, &val)) { - Obj *other_val = Hash_Fetch(twin, key); - if (!other_val || !Obj_Equals(other_val, val)) { return false; } + HashEntry *entry = (HashEntry*)self->entries; + HashEntry *const limit = entry + self->capacity; + + for (; entry < limit; entry++) { + if (entry->key && entry->key != TOMBSTONE) { + Obj *other_val = Hash_Fetch(twin, entry->key); + if (!other_val || !Obj_Equals(other_val, entry->value)) { + return false; + } + } } return true;
