/* Prune entries older than 3 seconds from the route cache */ void prune_route_cache(void* arg) { // This will store the next item in the linked list of hashmap entries hashmap_item_t next_item; // This will store a pointer to the route data struct route_data_t route_data; hashmap_item_t item; // Get the first item in the hashmap (first in the chronological sense) semaphore_P(route_cache_sem); item = hashmap_get_first(route_cache); // Go through all the items until we arrive at one that isn't ready for deletion while (item != NULL) { // Get the next item ahead of time, in case we delete this item next_item = hashmap_get_next(item); // Get the value of the hashmap, which is a route_data struct route_data = (route_data_t) hashmap_item_get_value(item); // Check if the entry is more than 3 seconds old if ((ticks - route_data->time_found) * PERIOD/MILLISECOND > 3000) { //printf("Deleting key %d\n", hashmap_item_get_key(item)); // Delete the route data struct delete_route_data(route_data); // Run hashmap delete, which will delete the hashmap_item struct (i.e. "item") hashmap_delete(route_cache, hashmap_item_get_key(item)); } else { // If the entry wasn't ready for deletion, then we can end (since the // linked list is maintained in chronological order of insertion) break; } // If we deleted the item, move to the next one item = next_item; } semaphore_V(route_cache_sem); // Once we're done, register the alarm to run again in 3 seconds register_alarm(3000, &prune_route_cache, NULL); }
struct cache_entry *index_file_exists(struct index_state *istate, const char *name, int namelen, int icase) { struct cache_entry *ce; lazy_init_name_hash(istate); ce = hashmap_get_from_hash(&istate->name_hash, memihash(name, namelen), NULL); while (ce) { if (same_name(ce, name, namelen, icase)) return ce; ce = hashmap_get_next(&istate->name_hash, ce); } return NULL; }
/* * Read stdin line by line and print result of commands to stdout: * * hash key -> strhash(key) memhash(key) strihash(key) memihash(key) * put key value -> NULL / old value * get key -> NULL / value * remove key -> NULL / old value * iterate -> key1 value1\nkey2 value2\n... * size -> tablesize numentries * * perfhashmap method rounds -> test hashmap.[ch] performance */ int main(int argc, char *argv[]) { char line[1024]; struct hashmap map; int icase; /* init hash map */ icase = argc > 1 && !strcmp("ignorecase", argv[1]); hashmap_init(&map, (hashmap_cmp_fn) (icase ? test_entry_cmp_icase : test_entry_cmp), 0); /* process commands from stdin */ while (fgets(line, sizeof(line), stdin)) { char *cmd, *p1 = NULL, *p2 = NULL; int l1 = 0, l2 = 0, hash = 0; struct test_entry *entry; /* break line into command and up to two parameters */ cmd = strtok(line, DELIM); /* ignore empty lines */ if (!cmd || *cmd == '#') continue; p1 = strtok(NULL, DELIM); if (p1) { l1 = strlen(p1); hash = icase ? strihash(p1) : strhash(p1); p2 = strtok(NULL, DELIM); if (p2) l2 = strlen(p2); } if (!strcmp("hash", cmd) && l1) { /* print results of different hash functions */ printf("%u %u %u %u\n", strhash(p1), memhash(p1, l1), strihash(p1), memihash(p1, l1)); } else if (!strcmp("add", cmd) && l1 && l2) { /* create entry with key = p1, value = p2 */ entry = alloc_test_entry(hash, p1, l1, p2, l2); /* add to hashmap */ hashmap_add(&map, entry); } else if (!strcmp("put", cmd) && l1 && l2) { /* create entry with key = p1, value = p2 */ entry = alloc_test_entry(hash, p1, l1, p2, l2); /* add / replace entry */ entry = hashmap_put(&map, entry); /* print and free replaced entry, if any */ puts(entry ? get_value(entry) : "NULL"); free(entry); } else if (!strcmp("get", cmd) && l1) { /* lookup entry in hashmap */ entry = hashmap_get_from_hash(&map, hash, p1); /* print result */ if (!entry) puts("NULL"); while (entry) { puts(get_value(entry)); entry = hashmap_get_next(&map, entry); } } else if (!strcmp("remove", cmd) && l1) { /* setup static key */ struct hashmap_entry key; hashmap_entry_init(&key, hash); /* remove entry from hashmap */ entry = hashmap_remove(&map, &key, p1); /* print result and free entry*/ puts(entry ? get_value(entry) : "NULL"); free(entry); } else if (!strcmp("iterate", cmd)) { struct hashmap_iter iter; hashmap_iter_init(&map, &iter); while ((entry = hashmap_iter_next(&iter))) printf("%s %s\n", entry->key, get_value(entry)); } else if (!strcmp("size", cmd)) { /* print table sizes */ printf("%u %u\n", map.tablesize, map.size); } else if (!strcmp("intern", cmd) && l1) { /* test that strintern works */ const char *i1 = strintern(p1); const char *i2 = strintern(p1); if (strcmp(i1, p1)) printf("strintern(%s) returns %s\n", p1, i1); else if (i1 == p1) printf("strintern(%s) returns input pointer\n", p1); else if (i1 != i2) printf("strintern(%s) != strintern(%s)", i1, i2); else printf("%s\n", i1); } else if (!strcmp("perfhashmap", cmd) && l1 && l2) { perf_hashmap(atoi(p1), atoi(p2)); } else { printf("Unknown command %s\n", cmd); } } hashmap_free(&map, 1); return 0; }