// Insert Ref with hash key Key into global Hash_Table . // Ref represents string S . static void Hash_Insert(String_Ref_t Ref, uint64 Key, char * S) { String_Ref_t H_Ref; char * T; int Shift; unsigned char Key_Check; int64 Ct, Probe, Sub; int i; Sub = HASH_FUNCTION (Key); Shift = HASH_CHECK_FUNCTION (Key); Hash_Check_Array [Sub] |= (((Check_Vector_t) 1) << Shift); Key_Check = KEY_CHECK_FUNCTION (Key); Probe = PROBE_FUNCTION (Key); Ct = 0; do { for (i = 0; i < Hash_Table [Sub] . Entry_Ct; i ++) if (Hash_Table [Sub] . Check [i] == Key_Check) { H_Ref = Hash_Table [Sub] . Entry [i]; T = Data + String_Start [getStringRefStringNum(H_Ref)] + getStringRefOffset(H_Ref); if (strncmp (S, T, Kmer_Len) == 0) { if (getStringRefLast(H_Ref)) { Extra_Ref_Ct ++; } Next_Ref [(String_Start [getStringRefStringNum(Ref)] + getStringRefOffset(Ref)) / (HASH_KMER_SKIP + 1)] = H_Ref; Extra_Ref_Ct ++; setStringRefLast(Ref, TRUELY_ZERO); Hash_Table [Sub] . Entry [i] = Ref; if (Hash_Table [Sub] . Hits [i] < HIGHEST_KMER_LIMIT) Hash_Table [Sub] . Hits [i] ++; return; } } if (i != Hash_Table [Sub] . Entry_Ct) { fprintf (stderr, "i = %d Sub = " F_S64 " Entry_Ct = %d\n", i, Sub, Hash_Table [Sub] . Entry_Ct); } assert (i == Hash_Table [Sub] . Entry_Ct); if (Hash_Table [Sub] . Entry_Ct < ENTRIES_PER_BUCKET) { setStringRefLast(Ref, TRUELY_ONE); Hash_Table [Sub] . Entry [i] = Ref; Hash_Table [Sub] . Check [i] = Key_Check; Hash_Table [Sub] . Entry_Ct ++; Hash_Entries ++; Hash_Table [Sub] . Hits [i] = 1; return; } Sub = (Sub + Probe) % HASH_TABLE_SIZE; } while (++ Ct < HASH_TABLE_SIZE); fprintf (stderr, "ERROR: Hash table full\n"); assert (FALSE); }
void bfilter_set(struct bloom_filter *bf, const void *buf, unsigned long buflen) { uint64_t hash; int i; for (i = 0; i < bf->nfunc; i++) { hash = HASH_FUNCTION(buf, buflen, bf->seeds[i]); bfilter_set_hash(bf, hash); } }
int bfilter_get(struct bloom_filter *bf, const void *buf, unsigned long buflen) { uint64_t hash; int i; for (i = 0; i < bf->nfunc; i++) { hash = HASH_FUNCTION(buf, buflen, bf->seeds[i]); if (bfilter_get_hash(bf, hash) == 0) return 0; } return 1; }
/* * Adds a new hash entry to the hash table. Returns != 0 when there is no * space left in the table. */ int hash_add (hash_t * hash, const hash_data_t * data) { int cell, free; int rc = FALSE; #if defined(MPI_HAS_INIT_THREAD_C) || defined(MPI_HAS_INIT_THREAD_F) pthread_mutex_lock(&hash_lock); #endif cell = HASH_FUNCTION (data->key); if (hash->table[cell].ovf_link == HASH_FREE) { hash->table[cell].ovf_link = HASH_NULL; /* No longer free */ hash->table[cell].data = *data; } else { /* * Get a free overflow cell */ if ((free = hash->ovf_free) == HASH_NULL) { fprintf (stderr, PACKAGE_NAME": hash_add: No space left in hash table. Size is %d+%d\n", HASH_TABLE_SIZE, HASH_OVERFLOW_SIZE); rc = TRUE; } else { hash->ovf_free = hash->overflow[free].next; /* * Insert free into overflow list of cell */ hash->overflow[free].next = hash->table[cell].ovf_link; hash->table[cell].ovf_link = free; /* * Update user data */ hash->overflow[free].data = *data; } } #if defined(MPI_HAS_INIT_THREAD_C) || defined(MPI_HAS_INIT_THREAD_F) pthread_mutex_unlock(&hash_lock); #endif return rc; }
PUBLIC HTAtom * HTAtom_for ARGS1(CONST char *, string) { int hash; HTAtom * a; /* First time around, clear hash table */ /* * Memory leak fixed. * 05-29-94 Lynx 2-3-1 Garrett Arch Blythe */ if (!initialised) { int i; for (i = 0; i < HASH_SIZE; i++) hash_table[i] = (HTAtom *) 0; initialised = YES; atexit(free_atoms); } /* Generate hash function */ hash = HASH_FUNCTION(string); /* Search for the string in the list */ for (a = hash_table[hash]; a; a = a->next) { if (0 == strcasecomp(a->name, string)) { /* CTRACE(tfp, "HTAtom: Old atom %p for `%s'\n", a, string); */ return a; /* Found: return it */ } } /* Generate a new entry */ a = (HTAtom *)malloc(sizeof(*a)); if (a == NULL) outofmem(__FILE__, "HTAtom_for"); a->name = (char *)malloc(strlen(string)+1); if (a->name == NULL) outofmem(__FILE__, "HTAtom_for"); strcpy(a->name, string); a->next = hash_table[hash]; /* Put onto the head of list */ hash_table[hash] = a; #ifdef NOT_DEFINED CTRACE(tfp, "HTAtom: New atom %p for `%s'\n", a, string); #endif /* NOT_DEFINED */ return a; }
// Set the empty bit to true for the hash table entry // corresponding to string s whose hash key is key . // Also set global String_Info . left/right_end_screened // true if the entry occurs near the left/right end, resp., // of the string in the hash table. If not found, add an // entry to the hash table and mark it empty. static void Hash_Mark_Empty(uint64 key, char * s) { String_Ref_t h_ref; char * t; unsigned char key_check; int64 ct, probe; int64 sub; int i, shift; sub = HASH_FUNCTION (key); key_check = KEY_CHECK_FUNCTION (key); probe = PROBE_FUNCTION (key); ct = 0; do { for (i = 0; i < Hash_Table [sub] . Entry_Ct; i ++) if (Hash_Table [sub] . Check [i] == key_check) { h_ref = Hash_Table [sub] . Entry [i]; t = Data + String_Start [getStringRefStringNum(h_ref)] + getStringRefOffset(h_ref); if (strncmp (s, t, Kmer_Len) == 0) { if (! getStringRefEmpty(Hash_Table [sub] . Entry [i])) Mark_Screened_Ends_Chain (Hash_Table [sub] . Entry [i]); setStringRefEmpty(Hash_Table [sub] . Entry [i], TRUELY_ONE); return; } } assert (i == Hash_Table [sub] . Entry_Ct); if (Hash_Table [sub] . Entry_Ct < ENTRIES_PER_BUCKET) { // Not found if (Use_Hopeless_Check) { Hash_Table [sub] . Entry [i] = Add_Extra_Hash_String (s); setStringRefEmpty(Hash_Table [sub] . Entry [i], TRUELY_ONE); Hash_Table [sub] . Check [i] = key_check; Hash_Table [sub] . Entry_Ct ++; Hash_Table [sub] . Hits [i] = 0; Hash_Entries ++; shift = HASH_CHECK_FUNCTION (key); Hash_Check_Array [sub] |= (((Check_Vector_t) 1) << shift); } return; } sub = (sub + probe) % HASH_TABLE_SIZE; } while (++ ct < HASH_TABLE_SIZE); fprintf (stderr, "ERROR: Hash table full\n"); assert (FALSE); }
/* * Searches for key in the hash table. Returns NULL when the key is not * found in the table. */ hash_data_t *hash_search (const hash_t * hash, MPI_Request key) { int cell, ovf; cell = HASH_FUNCTION (key); if (hash->table[cell].ovf_link == HASH_FREE) return NULL; if (hash->table[cell].data.key == key) return (hash_data_t *) & hash->table[cell].data; /* * Look for key in overflow list */ ovf = hash->table[cell].ovf_link; while (ovf != HASH_NULL) { if (hash->overflow[ovf].data.key == key) return (hash_data_t *) & hash->overflow[ovf].data; ovf = hash->overflow[ovf].next; } return NULL; }
/* The address has no anchor tag, for sure. */ PRIVATE HTParentAnchor0 * HTAnchor_findAddress_in_adult_table ARGS1( CONST DocAddress *, newdoc) { /* ** Check whether we have this node. */ int hash; HTList * adults; HTList *grownups; HTParentAnchor0 * foundAnchor; BOOL need_extra_info = (newdoc->post_data || newdoc->post_content_type || newdoc->bookmark || newdoc->isHEAD || newdoc->safe); /* * We need not free adult_table[] atexit - * it should be perfectly empty after free'ing all HText's. * (There is an error if it is not empty at exit). -LP */ /* ** Select list from hash table, */ hash = HASH_FUNCTION(newdoc->address); adults = &(adult_table[hash]); /* ** Search list for anchor. */ grownups = adults; while (NULL != (foundAnchor = (HTParentAnchor0 *)HTList_nextObject(grownups))) { if (HTSEquivalent(foundAnchor->address, newdoc->address) && ((!foundAnchor->info && !need_extra_info) || (foundAnchor->info && HTBEquivalent(foundAnchor->info->post_data, newdoc->post_data) && foundAnchor->info->isHEAD == newdoc->isHEAD))) { CTRACE((tfp, "Anchor %p with address `%s' already exists.\n", (void *)foundAnchor, newdoc->address)); return foundAnchor; } } /* ** Node not found: create new anchor. */ foundAnchor = HTParentAnchor0_new(newdoc->address, hash); CTRACE((tfp, "New anchor %p has hash %d and address `%s'\n", (void *)foundAnchor, hash, newdoc->address)); if (need_extra_info) { /* rare case, create a big structure */ HTParentAnchor *p = HTParentAnchor_new(foundAnchor); if (newdoc->post_data) BStrCopy(p->post_data, newdoc->post_data); if (newdoc->post_content_type) StrAllocCopy(p->post_content_type, newdoc->post_content_type); if (newdoc->bookmark) StrAllocCopy(p->bookmark, newdoc->bookmark); p->isHEAD = newdoc->isHEAD; p->safe = newdoc->safe; } HTList_linkObject(adults, foundAnchor, &foundAnchor->_add_adult); return foundAnchor; }
/* * Removes entry key in the hash table. Returns != 0 when key is not found in * the table. */ int hash_remove (hash_t * hash, MPI_Request key) { int cell, ovf, prev; int rc = FALSE; #if defined(MPI_HAS_INIT_THREAD_C) || defined(MPI_HAS_INIT_THREAD_F) pthread_mutex_lock(&hash_lock); #endif cell = HASH_FUNCTION (key); if (hash->table[cell].ovf_link == HASH_FREE) { #if SIZEOF_LONG == 8 fprintf (stderr, PACKAGE_NAME": hash_remove: Key %08lx not in hash table\n", (long) key); #elif SIZEOF_LONG == 4 fprintf (stderr, PACKAGE_NAME": hash_remove: Key %04x not in hash table\n", (long) key); #endif rc = TRUE; } else if (hash->table[cell].data.key == key) { /* * Remove the main entry */ if ((ovf = hash->table[cell].ovf_link) != HASH_NULL) { /* * Bring 1st overflow to main entry */ hash->table[cell].data = hash->overflow[ovf].data; hash->table[cell].ovf_link = hash->overflow[ovf].next; /* * Put freed ovf in free list */ hash->overflow[ovf].next = hash->ovf_free; hash->ovf_free = ovf; } else { hash->table[cell].ovf_link = HASH_FREE; /* Mark as free */ } } else { /* * Search key in overflow list */ ovf = hash->table[cell].ovf_link; prev = HASH_NULL; while (ovf != HASH_NULL && hash->overflow[ovf].data.key != key) { prev = ovf; ovf = hash->overflow[ovf].next; } if (ovf == HASH_NULL) /* Not found */ { #if SIZEOF_LONG == 8 fprintf (stderr, PACKAGE_NAME": hash_remove: Key %08lx not in hash table\n", (long) key); #elif SIZEOF_LONG == 4 fprintf (stderr, PACKAGE_NAME": hash_remove: Key %04x not in hash table\n", (long) key); #endif rc = TRUE; } else { if (prev == HASH_NULL) { hash->table[cell].ovf_link = hash->overflow[ovf].next; } else { hash->overflow[prev].next = hash->overflow[ovf].next; } hash->overflow[ovf].next = hash->ovf_free; hash->ovf_free = ovf; } } #if defined(MPI_HAS_INIT_THREAD_C) || defined(MPI_HAS_INIT_THREAD_F) pthread_mutex_unlock(&hash_lock); #endif return rc; }