[svn:parrot] r48569 - in trunk: include/parrot src src/pmc
chromatic at svn.parrot.org
chromatic at svn.parrot.org
Thu Aug 19 16:06:21 UTC 2010
Author: chromatic
Date: Thu Aug 19 16:06:20 2010
New Revision: 48569
URL: https://trac.parrot.org/parrot/changeset/48569
Log:
[hash] Added hash iteration macros.
Patch courtesy Luben Karavelov, TT #1741.
Modified:
trunk/include/parrot/hash.h
trunk/src/hash.c
trunk/src/packfile.c
trunk/src/pmc/callcontext.pmc
trunk/src/pmc/hashiterator.pmc
trunk/src/pmc/lexinfo.pmc
Modified: trunk/include/parrot/hash.h
==============================================================================
--- trunk/include/parrot/hash.h Thu Aug 19 06:49:05 2010 (r48568)
+++ trunk/include/parrot/hash.h Thu Aug 19 16:06:20 2010 (r48569)
@@ -78,6 +78,49 @@
hash_hash_key_fn hash_val;
};
+/* Utility macros - use them, do not reinvent the weel */
+#define parrot_hash_iterate parrot_hash_iterate_linear
+
+#define parrot_hash_iterate_linear(_hash, _code) \
+{ \
+ HashBucket *_bucket = (_hash)->buckets; \
+ UINTVAL _found = 0; \
+ while (_found < _hash->entries){ \
+ if (_bucket->key){ \
+ _code \
+ _found++; \
+ } \
+ _bucket++; \
+ } \
+}
+
+#define parrot_hash_iterate_indexed(_hash, _code) \
+{ \
+ INTVAL _loc; \
+ for (_loc = (_hash)->mask; _loc >= 0; --_loc) { \
+ HashBucket *_bucket = (_hash)->bucket_indices[_loc]; \
+ while (_bucket) { \
+ _code \
+ _bucket = _bucket->next; \
+ } \
+ } \
+}
+
+
+#define parrot_hash_iterator_advance(_hash,_bucket,_loc) \
+{ \
+ /* Try to advance current bucket */ \
+ if ((_bucket)) \
+ (_bucket) = (_bucket)->next; \
+ while (!(_bucket)) { \
+ /* If there is no more buckets */ \
+ if ((_loc) == (INTVAL)(_hash)->mask+1) \
+ break; \
+ (_bucket) = (_hash)->bucket_indices[_loc++]; \
+ } \
+}
+
+
typedef void (*value_free)(ARGFREE(void *));
/* To avoid creating OrderedHashItem PMC we reuse FixedPMCArray PMC */
Modified: trunk/src/hash.c
==============================================================================
--- trunk/src/hash.c Thu Aug 19 06:49:05 2010 (r48568)
+++ trunk/src/hash.c Thu Aug 19 16:06:20 2010 (r48569)
@@ -512,22 +512,10 @@
parrot_mark_hash_keys(PARROT_INTERP, ARGIN(Hash *hash))
{
ASSERT_ARGS(parrot_mark_hash_keys)
- const UINTVAL entries = hash->entries;
- UINTVAL found = 0;
- UINTVAL i;
-
- HashBucket *bucket = hash->buckets;
-
- for (i= 0; i <= hash->mask; ++i, ++bucket) {
- if (bucket->key){
-
- PARROT_ASSERT(bucket->key);
- Parrot_gc_mark_PObj_alive(interp, (PObj *)bucket->key);
-
- if (++found >= entries)
- break;
- }
- }
+ parrot_hash_iterate(hash,
+ PARROT_ASSERT(_bucket->key);
+ Parrot_gc_mark_PObj_alive(interp, (PObj *)_bucket->key);
+ );
}
@@ -545,24 +533,13 @@
parrot_mark_hash_values(PARROT_INTERP, ARGIN(Hash *hash))
{
ASSERT_ARGS(parrot_mark_hash_values)
- const UINTVAL entries = hash->entries;
- UINTVAL found = 0;
- UINTVAL i;
-
- HashBucket *bucket = hash->buckets;
-
- for (i= 0; i <= hash->mask; ++i, ++bucket) {
- if (bucket->key){
-
- PARROT_ASSERT(bucket->value);
- Parrot_gc_mark_PObj_alive(interp, (PObj *)bucket->value);
-
- if (++found >= entries)
- break;
- }
- }
+ parrot_hash_iterate(hash,
+ PARROT_ASSERT(_bucket->value);
+ Parrot_gc_mark_PObj_alive(interp, (PObj *)_bucket->value);
+ );
}
+
/*
=item C<static void parrot_mark_hash_both(PARROT_INTERP, Hash *hash)>
@@ -577,24 +554,12 @@
parrot_mark_hash_both(PARROT_INTERP, ARGIN(Hash *hash))
{
ASSERT_ARGS(parrot_mark_hash_both)
- const UINTVAL entries = hash->entries;
- UINTVAL found = 0;
- UINTVAL i;
-
- HashBucket *bucket = hash->buckets;
-
- for (i= 0; i <= hash->mask; ++i, ++bucket) {
- if (bucket->key){
- PARROT_ASSERT(bucket->key);
- Parrot_gc_mark_PObj_alive(interp, (PObj *)bucket->key);
-
- PARROT_ASSERT(bucket->value);
- Parrot_gc_mark_PObj_alive(interp, (PObj *)bucket->value);
-
- if (++found >= entries)
- break;
- }
- }
+ parrot_hash_iterate(hash,
+ PARROT_ASSERT(_bucket->key);
+ Parrot_gc_mark_PObj_alive(interp, (PObj *)_bucket->key);
+ PARROT_ASSERT(_bucket->value);
+ Parrot_gc_mark_PObj_alive(interp, (PObj *)_bucket->value);
+ );
}
/*
@@ -714,41 +679,38 @@
const size_t entries = hash->entries;
size_t i;
- for (i = 0; i < entries; ++i) {
- HashBucket * const b = hash->buckets + i;
-
+ parrot_hash_iterate(hash,
switch (key_type) {
case Hash_key_type_int:
- VTABLE_push_integer(interp, info, (INTVAL)b->key);
+ VTABLE_push_integer(interp, info, (INTVAL)_bucket->key);
break;
case Hash_key_type_STRING:
- VTABLE_push_string(interp, info, (STRING *)b->key);
+ VTABLE_push_string(interp, info, (STRING *)_bucket->key);
break;
case Hash_key_type_PMC:
- VTABLE_push_pmc(interp, info, (PMC *)b->key);
+ VTABLE_push_pmc(interp, info, (PMC *)_bucket->key);
break;
default:
Parrot_ex_throw_from_c_args(interp, NULL, 1,
"unimplemented key type");
break;
}
-
switch (entry_type) {
case enum_hash_int:
- VTABLE_push_integer(interp, info, (INTVAL)b->value);
+ VTABLE_push_integer(interp, info, (INTVAL)_bucket->value);
break;
case enum_hash_string:
- VTABLE_push_string(interp, info, (STRING *)b->value);
+ VTABLE_push_string(interp, info, (STRING *)_bucket->value);
break;
case enum_hash_pmc:
- VTABLE_push_pmc(interp, info, (PMC *)b->value);
+ VTABLE_push_pmc(interp, info, (PMC *)_bucket->value);
break;
default:
Parrot_ex_throw_from_c_args(interp, NULL, 1,
"unimplemented value type");
break;
}
- }
+ );
}
@@ -1121,17 +1083,10 @@
parrot_chash_destroy(PARROT_INTERP, ARGMOD(Hash *hash))
{
ASSERT_ARGS(parrot_chash_destroy)
- UINTVAL i;
-
- for (i = 0; i <= hash->mask; ++i) {
- HashBucket *bucket = hash->bucket_indices[i];
- while (bucket) {
- mem_gc_free(interp, bucket->key);
- mem_gc_free(interp, bucket->value);
- bucket = bucket->next;
- }
- }
-
+ parrot_hash_iterate(hash,
+ mem_gc_free(interp, _bucket->key);
+ mem_gc_free(interp, _bucket->value);
+ );
parrot_hash_destroy(interp, hash);
}
@@ -1472,33 +1427,30 @@
ARGOUT(Hash *dest), int deep)
{
ASSERT_ARGS(parrot_hash_clone_prunable)
- UINTVAL entries = hash->entries;
- UINTVAL i;
- for (i = 0; i < entries; ++i) {
+ parrot_hash_iterate(hash,
void *valtmp;
- HashBucket *b = hash->buckets + i;
- void * const key = b->key;
+ void * const key = _bucket->key;
switch (hash->entry_type) {
case enum_type_undef:
case enum_type_ptr:
case enum_type_INTVAL:
- valtmp = (void *)b->value;
+ valtmp = (void *)_bucket->value;
break;
case enum_type_STRING:
- valtmp = b->value;
+ valtmp = _bucket->value;
break;
case enum_type_PMC:
- if (PMC_IS_NULL((PMC *)b->value))
+ if (PMC_IS_NULL((PMC *)_bucket->value))
valtmp = (void *)PMCNULL;
else
if (deep)
- valtmp = (void *)VTABLE_clone(interp, (PMC*)b->value);
+ valtmp = (void *)VTABLE_clone(interp, (PMC*)_bucket->value);
else
- valtmp = b->value;
+ valtmp = _bucket->value;
break;
default:
@@ -1506,10 +1458,9 @@
Parrot_ex_throw_from_c_args(interp, NULL, -1,
"hash corruption: type = %d\n", hash->entry_type);
};
-
if (key)
parrot_hash_put(interp, dest, key, valtmp);
- }
+ );
}
/*
Modified: trunk/src/packfile.c
==============================================================================
--- trunk/src/packfile.c Thu Aug 19 06:49:05 2010 (r48568)
+++ trunk/src/packfile.c Thu Aug 19 16:06:20 2010 (r48569)
@@ -3471,22 +3471,12 @@
if (!hash)
return;
- for (i = 0; i <= hash->mask; ++i) {
- HashBucket *bucket = hash->bucket_indices[i];
-
- while (bucket) {
- PackFile_ConstTable * const table =
- (PackFile_ConstTable *)bucket->key;
- PackFile_Constant * const orig_consts = table->constants;
- PackFile_Constant * const consts =
- (PackFile_Constant *) bucket->value;
- INTVAL j;
-
- mem_gc_free(interp, consts);
- bucket = bucket->next;
- }
- }
-
+ parrot_hash_iterate(hash,
+ PackFile_ConstTable * const table = (PackFile_ConstTable *)_bucket->key;
+ PackFile_Constant * const orig_consts = table->constants;
+ PackFile_Constant * const consts = (PackFile_Constant *) _bucket->value;
+ mem_gc_free(interp, consts);
+ );
parrot_hash_destroy(interp, hash);
}
Modified: trunk/src/pmc/callcontext.pmc
==============================================================================
--- trunk/src/pmc/callcontext.pmc Thu Aug 19 06:49:05 2010 (r48568)
+++ trunk/src/pmc/callcontext.pmc Thu Aug 19 16:06:20 2010 (r48569)
@@ -468,17 +468,10 @@
mark_hash(PARROT_INTERP, ARGIN(Hash *h))
{
ASSERT_ARGS(mark_hash)
- INTVAL i;
-
- for (i = h->mask; i >= 0; --i) {
- HashBucket *b = h->bucket_indices[i];
-
- while (b) {
- Parrot_gc_mark_STRING_alive(interp, (STRING *)b->key);
- mark_cell(interp, (Pcc_cell *)b->value);
- b = b->next;
- }
- }
+ parrot_hash_iterate(h,
+ Parrot_gc_mark_STRING_alive(interp, (STRING *)_bucket->key);
+ mark_cell(interp, (Pcc_cell *)_bucket->value);
+ );
}
/*
@@ -500,19 +493,11 @@
/* yes, this *looks* risky, but it's a Parrot STRING hash internally */
if (hash && hash->entries) {
- UINTVAL i, j = 0;
+ UINTVAL j = 0;
PMC *result = Parrot_pmc_new_init_int(interp, enum_class_FixedStringArray, hash->entries);
-
- for (i = 0; i <= hash->mask; ++i) {
- HashBucket *b = hash->bucket_indices[i];
-
- while (b) {
- VTABLE_set_string_keyed_int(interp, result,
- j++, (STRING *)b->key);
- b = b->next;
- }
- }
-
+ parrot_hash_iterate(hash,
+ VTABLE_set_string_keyed_int(interp, result, j++, (STRING *)_bucket->key);
+ );
return result;
}
@@ -702,17 +687,9 @@
GET_ATTR_hash(INTERP, SELF, hash);
if (hash) {
- UINTVAL i;
-
- for (i = 0; i <= hash->mask; ++i) {
- HashBucket *b = hash->bucket_indices[i];
-
- while (b) {
- FREE_CELL(INTERP, (Pcc_cell *)b->value);
- b = b->next;
- }
- }
-
+ parrot_hash_iterate(hash,
+ FREE_CELL(INTERP, (Pcc_cell *)_bucket->value);
+ );
parrot_hash_destroy(INTERP, hash);
SET_ATTR_hash(INTERP, SELF, NULL);
}
@@ -740,17 +717,9 @@
}
if (hash) {
- UINTVAL i;
-
- for (i = 0; i <= hash->mask; ++i) {
- HashBucket *b = hash->bucket_indices[i];
-
- while (b) {
- FREE_CELL(INTERP, (Pcc_cell *)b->value);
- b = b->next;
- }
- }
-
+ parrot_hash_iterate(hash,
+ FREE_CELL(INTERP, (Pcc_cell *)_bucket->value);
+ );
parrot_hash_destroy(INTERP, hash);
}
Modified: trunk/src/pmc/hashiterator.pmc
==============================================================================
--- trunk/src/pmc/hashiterator.pmc Thu Aug 19 06:49:05 2010 (r48568)
+++ trunk/src/pmc/hashiterator.pmc Thu Aug 19 16:06:20 2010 (r48569)
@@ -78,24 +78,9 @@
advance_to_next(PARROT_INTERP, ARGMOD(PMC *self))
{
ASSERT_ARGS(advance_to_next)
-
Parrot_HashIterator_attributes * const attrs = PARROT_HASHITERATOR(self);
- HashBucket *bucket = attrs->bucket;
-
- /* Try to advance current bucket */
- if (bucket)
- bucket = bucket->next;
-
- while (!bucket) {
- /* If there is no more buckets */
- if (attrs->pos == attrs->total_buckets)
- break;
-
- bucket = attrs->parrot_hash->bucket_indices[attrs->pos++];
- }
- attrs->bucket = bucket;
+ parrot_hash_iterator_advance(attrs->parrot_hash, attrs->bucket, attrs->pos);
--attrs->elements;
-
return;
}
Modified: trunk/src/pmc/lexinfo.pmc
==============================================================================
--- trunk/src/pmc/lexinfo.pmc Thu Aug 19 06:49:05 2010 (r48568)
+++ trunk/src/pmc/lexinfo.pmc Thu Aug 19 16:06:20 2010 (r48569)
@@ -99,25 +99,11 @@
if (Parrot_str_equal(INTERP, what, CONST_STRING(INTERP, "symbols"))) {
PMC * const result = Parrot_pmc_new(INTERP, enum_class_ResizableStringArray);
const Hash *hash = (Hash *)SELF.get_pointer();
- const UINTVAL entries = hash->entries;
- UINTVAL found = 0;
- INTVAL i;
-
- for (i = hash->mask; i >= 0; --i) {
- HashBucket *bucket = hash->bucket_indices[i];
- while (bucket) {
- if (++found > entries)
- Parrot_ex_throw_from_c_args(INTERP, NULL, 1,
- "Detected corruption at LexInfo hash %p entries %d",
- hash, (int)entries);
-
- PARROT_ASSERT(bucket->key);
- VTABLE_push_string(INTERP, result, (STRING *)bucket->key);
-
- bucket = bucket->next;
- }
- }
+ parrot_hash_iterate(hash,
+ PARROT_ASSERT(_bucket->key);
+ VTABLE_push_string(INTERP, result, (STRING *)_bucket->key);
+ );
return result;
}
More information about the parrot-commits
mailing list