// Function to be mapped over curRHT to generate next level in nextRHT. void generateNextLevel(void* key, void* value) { uint64* state = (uint64*)key; uint8* level = (uint8*)value; if(*level == CUR_LEVEL) { uint64 nbrs[PERM_LEN-1]; genAll(*state, nbrs); uint8 nextLevel = CUR_LEVEL + 1; int i; for(i=0; i<PERM_LEN-1; i++) { RoomyHashTable_insert(nextRHT, &(nbrs[i]), &nextLevel); } } }
/* Adds the node to the RoomyGraph (RG). NOTE: This is a delayed operation therefore you must call RoomyGraph_sync before the node is ensured to be added to the RG */ void RoomyGraph_addNode(RoomyGraph *g, uint64 node) { // We are adding 1 because that is what stores the stored // number of edges. void *EMPTY = calloc((1 + g->maxEdges), sizeof(uint64)); RoomyHashTable_insert(g->graph, &node, EMPTY); }
// Top level function for method using one RoomyHashTable void pancakeHashTable() { Roomy_log("BEGINNING %i PANCAKE BFS: RoomyHashTable version\n", PERM_LEN); // Set element counters (assuming level 0 has been completed). uint64 levelSize = 1; // number of elements in curRHT uint64 totalElts = 1; // total number of elements see so far // Create hash tables CUR_LEVEL = 0; allRHT = RoomyHashTable_make("allRHT", sizeof(uint64), sizeof(uint8), N_STATES); curRHT = RoomyHashTable_make("lev0RHT", sizeof(uint64), sizeof(uint8), levelSize); nextRHT = RoomyHashTable_make("lev1RHT", sizeof(uint64), sizeof(uint8), levelSize * PERM_LEN); // Set identity element Perm ident; getIdentPerm(ident); uint64 identPos = rank(ident); RoomyHashTable_insert(allRHT, &identPos, &CUR_LEVEL); RoomyHashTable_sync(allRHT); RoomyHashTable_insert(curRHT, &identPos, &CUR_LEVEL); RoomyHashTable_sync(curRHT); Roomy_log("Level %i done: %lli elements\n", CUR_LEVEL, levelSize); // While current level is not empty while (levelSize > 0) { // map over cur level, add neighbors to next level RoomyHashTable_map(curRHT, generateNextLevel); RoomyHashTable_sync(nextRHT); // remove all elts in seen from next (by mapping over seen and calling // remove) RoomyHashTable_map(allRHT, removeDupes); RoomyHashTable_sync(nextRHT); // add all elts in next to seen (by mapping over next and calling update) RoomyHashTable_map(nextRHT, recordNewElts); RoomyHashTable_sync(allRHT); // rotate levels RoomyHashTable_destroy(curRHT); curRHT = nextRHT; levelSize = RoomyHashTable_size(curRHT); CUR_LEVEL++; char levName[1024]; sprintf(levName, "lev%iRHT", CUR_LEVEL + 1); // New table size is 30% bigger than the next level, to avoid doubling // of hash table capacity. But, it doesn't need to be bigger than the // entire search space. (PERM_LEN-1 is the branching factor.) uint64 tableSize = levelSize * (PERM_LEN-1) * 13 / 10; if (tableSize > N_STATES) { tableSize = N_STATES; } nextRHT = RoomyHashTable_make(levName, sizeof(uint64), sizeof(uint8), tableSize); // Confirm size reported by reduction matches level size. uint64 numEltsFromReduce = 0; RoomyHashTable_reduce(curRHT, &numEltsFromReduce, sizeof(uint64), addOneToAns, sumAns); assert(numEltsFromReduce == levelSize); totalElts = RoomyHashTable_size(allRHT); Roomy_log("Level %i done: %lli elements\n", CUR_LEVEL, levelSize); } Roomy_log("PANCAKE BFS DONE\n"); }
// To be mapped over nextRHT to add all new elements to allRHT. void recordNewElts(void* key, void* value) { RoomyHashTable_insert(allRHT, key, value); }