int vnet_peer_add(VarpAddr *addr, uint16_t port){ int err = 0; unsigned long flags; VnetPeer *peer; vnet_peer_write_lock(flags); peer = HashTable_get(vnet_peer_table, addr); if(peer){ VnetPeer_incref(peer); goto exit; } peer = ALLOCATE(VnetPeer); if(!peer){ err = -ENOMEM; goto exit; } peer->addr = *addr; peer->port = port; VnetPeer_incref(peer); if(!HashTable_add(vnet_peer_table, &peer->addr, peer)){ VnetPeer_decref(peer); err = -ENOMEM; } exit: vnet_peer_write_unlock(flags); return err; }
int main(int argc, char *argv[]) { HashTable ht = newHashTable(65535); HashTable_put(ht, "1", "two"); HashTable_put(ht, "2", "three"); HashTable_put(ht, "3", "five"); HashTable_put(ht, "4", "seven"); HashTable_put(ht, "5", "eleven"); HashTable_put(ht, "6", "thirteen"); HashTable_put(ht, "7", "seventeen"); HashTable_remove(ht, "1"); HashTable_remove(ht, "2"); HashTable_remove(ht, "6"); HashTable_remove(ht, "7"); HashTable_put(ht, "3", "not allowed"); printf("%s\n", HashTable_get(ht, "1")); printf("%s\n", HashTable_get(ht, "2")); printf("%s\n", HashTable_get(ht, "3")); printf("%s\n", HashTable_get(ht, "4")); printf("%s\n", HashTable_get(ht, "5")); printf("%s\n", HashTable_get(ht, "6")); printf("%s\n", HashTable_get(ht, "7")); printf("size: %d\n", HashTable_size(ht)); freeHashTable(&ht); return 0; }
int vnet_peer_get(VarpAddr *addr, VnetPeer **peer){ unsigned long flags; vnet_peer_read_lock(flags); *peer = HashTable_get(vnet_peer_table, addr); VnetPeer_incref(*peer); vnet_peer_read_unlock(flags); return (*peer ? 0 : -ENOENT); }
HEADER_DECLARE atom_t intern(Term* str){ FRAME_ENTER_1(str); assert(str->type == STRING, "cannot intern non-string"); FRAME_LOCAL(term) = chase(HashTable_get(root.interned, str)); if(!Var_is_terminal(term)){ guarantee(is_Atom(term), "interned term is not an atom"); D_ATOM{ debug("already interned `%s' as %lu\n", str->data.string.ptr, term->data.functor.atom); } FRAME_RETURN(atom_t, term->data.functor.atom); }
HEADER_DECLARE atom_t intern(Term* str){ FRAME_ENTER_1(str); assert(str->type == STRING, "cannot intern non-string"); FRAME_LOCAL(term) = chase(HashTable_get(root.interned, str)); if(!Var_is_terminal(term)){ guarantee(is_Atom(term), "interned term is not an atom"); D_ATOM{ debug("already interned `%s' as %lu\n", str->data.string.ptr, term->data.functor.atom); } FRAME_RETURN(atom_t, term->data.functor.atom); } atom_t atom = next_free_atom++; FRAME_LOCAL(tatom) = Atom(atom); set_var(term, tatom); FRAME_LOCAL(rev) = HashTable_get(root.atom_names, tatom); set_var(rev, str); D_ATOM{ debug("interning %s as %lu\n", str->data.string.ptr, atom); } FRAME_RETURN(atom_t, atom); } HEADER_DECLARE atom_t intern_nt(char* string){ FRAME_ENTER; FRAME_LOCAL(s) = String_nt(string); FRAME_RETURN(atom_t, intern(s)); } void intern_prim(char* string, atom_t atom){
void testHashTable() { typedef struct { uint64 key; uint64 data; } TestData; int initialCapacity = 1000; int numEntries = 5000; // make hash table HashTable htb = HashTable_make(sizeof(uint64), sizeof(uint64), initialCapacity); // insert data, and some duplicates TestData entries[numEntries]; int i; for (i = 0; i < numEntries; i++) { entries[i].key = rand(); entries[i].data = rand(); HashTable_insert(&htb, &(entries[i].key), &(entries[i].data)); // insert a previous duplicate if (i > 10) { HashTable_insert(&htb, &(entries[i-10].key), &(entries[i-10].data)); } assert(HashTable_size(&htb) == i+1); assert(HashTable_capacity(&htb) > i); } // check data for (i = 0; i < numEntries; i++) { uint64 *data = (uint64*)HashTable_get(&htb, &(entries[i].key)); assert(data != NULL); assert(*data == entries[i].data); } assert(HashTable_size(&htb) == numEntries); assert(HashTable_capacity(&htb) >= numEntries); // remove and re-insert some elements int numRemoved = 0; for (i = 0; i < numEntries; i = i + 2) { HashTable_delete(&htb, &(entries[i].key)); numRemoved++; assert(HashTable_size(&htb) == numEntries - numRemoved); assert(HashTable_get(&htb, &(entries[i].key)) == NULL); } for (i = 0; i < numEntries; i = i + 2) { HashTable_insert(&htb, &(entries[i].key), &(entries[i].data)); numRemoved--; assert(HashTable_size(&htb) == numEntries - numRemoved); assert(HashTable_get(&htb, &(entries[i].key)) != NULL); } // save to file, destroy, and recreate from file char *filename = "/tmp/roomyTestHashTable"; HashTable_fileSave(&htb, filename); HashTable_destroy(&htb); htb = HashTable_makeFromFiles(filename); for (i = 0; i < numEntries; i++) { uint64 *data = (uint64*)HashTable_get(&htb, &(entries[i].key)); assert(data != NULL); assert(*data == entries[i].data); } assert(HashTable_size(&htb) == numEntries); assert(HashTable_capacity(&htb) >= numEntries); HashTable_destroy(&htb); // make using mmap htb = HashTable_makeMapped(filename); for (i = 0; i < numEntries; i++) { uint64 *data = (uint64*)HashTable_get(&htb, &(entries[i].key)); assert(data != NULL); assert(*data == entries[i].data); } assert(HashTable_size(&htb) == numEntries); assert(HashTable_capacity(&htb) >= numEntries); HashTable_destroy(&htb); assert(HashTable_removeFiles(filename) == 0); printf("HASH TABLE PASSED TESTS\n"); }