static int emit_code_defs(const char *to) { const char *tmp = "vmi.tmp"; FILE *out = fopen(tmp, "w"); int i; fprintf(out, "/* File: %s\n\n", to); fprintf(out, " This file provides the definition of type code.\n"); fprintf(out, "\n"); fprintf(out, " Note: this file is generated by %s from %s. DO NOT EDIT", program, vmi_file); fprintf(out, " \n"); fprintf(out, "*/\n\n"); fprintf(out, "typedef enum\n"); fprintf(out, "{\n"); for(i=0; i<vmi_count; i++) { fprintf(out, " %s,\n", vmi_list[i].name); } fprintf(out, " VMI_END_LIST\n"); fprintf(out, "} vmi;\n\n"); fprintf(out, "#define I_HIGHEST ((int)VMI_END_LIST)\n"); fprintf(out, "#define VM_SIGNATURE 0x%x\n", MurmurHashAligned2(synopsis, syn_size, 0x12345678)); fclose(out); return update_file(tmp, to); }
word intern_indirect(indirect_table *tab, word val, int create ARG_LD) { Word idata = addressIndirect(val); /* points at header */ size_t isize = wsizeofInd(*idata); /* include header */ unsigned int key = MurmurHashAligned2(idata+1, isize*sizeof(word), MURMUR_SEED); indirect_buckets *buckets; for(;;) { buckets = acquire_itable_buckets(tab); unsigned int ki = key & (buckets->size-1); indirect *head = buckets->buckets[ki]; indirect *h; acquire_itable_bucket(&buckets->buckets[ki]); for(h=buckets->buckets[ki]; h; h = h->next) { unsigned int ref = h->references; if ( INDIRECT_IS_VALID(ref) && idata[0] == h->header && memcmp(idata+1, h->data, isize*sizeof(word)) == 0 ) { if ( bump_ref(h, ref) ) { release_itable_buckets(); return h->handle; } } } if ( TIGHT(buckets, tab) ) { simpleMutexLock(&tab->mutex); rehash_indirect_table(tab); simpleMutexUnlock(&tab->mutex); } if ( buckets != tab->table || head != buckets->buckets[ki] ) continue; /* try again */ if ( create ) { indirect *h = reserve_indirect(tab, val PASS_LD); h->next = buckets->buckets[ki]; if ( !COMPARE_AND_SWAP(&buckets->buckets[ki], head, h) || buckets != tab->table ) { PL_free(h->data); h->references = 0; continue; /* try again */ } h->references = 1 | INDIRECT_VALID_REFERENCE | INDIRECT_RESERVED_REFERENCE; ATOMIC_INC(&tab->count); release_itable_buckets(); return h->handle; } else { release_itable_buckets(); return 0; } } }
void ring_murmurhash_aligned2(void *pPointer) { char *key = NULL; int keylen; int seed = 0; uint32_t out; int ret_type = 0; if (RING_API_PARACOUNT < 2 || RING_API_PARACOUNT > 3) { RING_API_ERROR(RING_API_MISS2PARA); return ; } if (!RING_API_ISSTRING(1)) { RING_API_ERROR("murmurhash_aligned2 expects the first parameter to be a string"); return; } if (!RING_API_ISNUMBER(2)) { RING_API_ERROR("murmurhash_aligned2 expects the first parameter to be an integer"); return; } key = RING_API_GETSTRING(1); keylen = strlen(key); seed = RING_API_GETNUMBER(2); if (RING_API_PARACOUNT == 3) { if (RING_API_ISNUMBER(3)) { ret_type = RING_API_GETNUMBER(3); if (!is_bool(ret_type)) { RING_API_ERROR("Third parameter should be boolean value\n"); } } else { RING_API_ERROR("murmurhash_aligned2 expects the third parameter to be an integer\n"); } } out = MurmurHashAligned2(key, keylen, seed); MH_RETURN_INT(out, ret_type); }
static void rehash_indirect_table(indirect_table *tab) { if ( TIGHT(tab->table, tab) ) { indirect_buckets *oldtab = tab->table; indirect_buckets *newtab = PL_malloc(sizeof(*newtab)); unsigned int mask; size_t index; int i, last=FALSE; newtab->size = oldtab->size * 2; newtab->buckets = PL_malloc(newtab->size*sizeof(*newtab->buckets)); memset(newtab->buckets, 0, newtab->size*sizeof(*newtab->buckets)); newtab->prev = oldtab; mask = newtab->size - 1; for(index=1, i=0; !last; i++) { size_t upto = (size_t)2<<i; indirect *b = tab->array.blocks[i]; if ( upto >= tab->highest ) { upto = tab->highest; last = TRUE; } for(; index<upto; index++) { indirect *a = b+index; if ( INDIRECT_IS_VALID(a->references) ) { size_t sz = wsizeofInd(a->header); unsigned int v; v = MurmurHashAligned2(a->data, sz*sizeof(word), MURMUR_SEED) & mask; a->next = newtab->buckets[v]; newtab->buckets[v] = a; } } } tab->table = newtab; } }