bool Hashtable::Put(const void *key, void *value) { Entry *entry = GetHashEntry(key); int hash = fHashFunc(key); int index; if (entry) return true; fModCount++; if (fCount >= fThreshold) Rehash(); index = hash % fCapacity; fTable[index] = new Entry(fTable[index], key, value); fCount++; return true; }
int EnvironmentROBARM::GetRandomState() { short unsigned int coord[NUMOFLINKS]; double angles[NUMOFLINKS]; short unsigned int endeffx, endeffy; EnvROBARMHashEntry_t* HashEntry = NULL; printf("picking a random state...\n"); while(1) { //iterate over links for(int i = 0; i < NUMOFLINKS; i++) { //give it a shot coord[i] = (short unsigned int)(EnvROBARMCfg.anglevals[i]*(((double)rand())/(RAND_MAX+1))); } /* //iterate over links double endx[NUMOFLINKS]; double endy[NUMOFLINKS]; double x0, y0, x1, y1; for(int i = 0; i < NUMOFLINKS; i++) { int j = 0; //set the start of the link if(i == 0) Cell2ContXY(EnvROBARMCfg.BaseX_c, EnvROBARMCfg.EnvHeight_c-1,&x0,&y0); else { x0 = endx[i-1]; y0 = endy[i-1]; } //try to set the angle int numoftrials = 100; for(j = 0; j < numoftrials; j++) { //give it a shot coord[i] = EnvROBARMCfg.anglevals[i]*(((double)rand())/(RAND_MAX+1)); //check the new link ComputeContAngles(coord, angles); x1 = x0 + EnvROBARMCfg.LinkLength_m[i]*cos(angles[i]); y1 = y0 - EnvROBARMCfg.LinkLength_m[i]*sin(angles[i]); //check the validity of the corresponding line segment if(IsValidLineSegment(x0,y0,x1,y1, EnvROBARMCfg.Grid2D, NULL)) { break; } } //see if we found it if(j == numoftrials) { //failed, reset printf("have to reset\n"); break; } else { endx[i] = x1; endy[i] = y1; } } */ //if not valid then try something else if(!IsValidCoord(coord)) { //printf("ERROR: we could not have gotten an invalid sample\n"); continue; } else //done - found break; } printf("done\n"); //compute end effector ComputeContAngles(coord, angles); ComputeEndEffectorPos(angles, &endeffx, &endeffy); bool bIsGoal = false; if(endeffx == EnvROBARMCfg.EndEffGoalX_c && endeffy == EnvROBARMCfg.EndEffGoalY_c) { bIsGoal = true; //printf("goal succ is generated\n"); } if((HashEntry = GetHashEntry(coord, NUMOFLINKS, bIsGoal)) == NULL) { //have to create a new entry HashEntry = CreateNewHashEntry(coord, NUMOFLINKS, endeffx, endeffy); } return HashEntry->stateID; }
void EnvironmentROBARM::GetRandomSUCCS(CMDPSTATE* SourceState, vector<int>* SuccIDV, vector<int>* CLowV, int K) { short unsigned int coord[NUMOFLINKS]; short unsigned int endeffx, endeffy; double angles[NUMOFLINKS]; //clear the successor array SuccIDV->clear(); CLowV->clear(); //the number of successors int numofsuccs = K; //goal state should be absorbing if(SourceState->StateID == EnvROBARM.goalHashEntry->stateID) return; //get X, Y for the state EnvROBARMHashEntry_t* HashEntry = EnvROBARM.StateID2CoordTable[SourceState->StateID]; //iterate through random actions for (int succind = 0; succind < numofsuccs; succind++) { //pick the coordinate that will have dist = longactiondist int maxcoordind = (int)(NUMOFLINKS*(((double)rand())/RAND_MAX)); //now iterate over the coordinates for (int cind = 0; cind < NUMOFLINKS; cind++) { if(cind == maxcoordind) { //we know the magnitude and just need to set sign if((((double)rand())/RAND_MAX) > 0.5) { //positive sign coord[cind] = (HashEntry->coord[cind] + ROBARM_LONGACTIONDIST_CELLS)%EnvROBARMCfg.anglevals[cind]; } else { //negative sign if(HashEntry->coord[cind] < ROBARM_LONGACTIONDIST_CELLS) coord[cind] = HashEntry->coord[cind] + EnvROBARMCfg.anglevals[cind] - ROBARM_LONGACTIONDIST_CELLS; else coord[cind] = HashEntry->coord[cind] - ROBARM_LONGACTIONDIST_CELLS; //if(coord[cind] < 0) //{ // printf("ERROR: ROBARM_LONGACTIONDIST_CELLS is too large for dim %d\n", cind); // exit(1); //} } } else { //any value within ROBARM_LONGACTIONDIST_CELLS from the center int offset = (int)(ROBARM_LONGACTIONDIST_CELLS*(((double)rand())/RAND_MAX)); if((((double)rand())/RAND_MAX) > 0.5) offset = -offset; //we know the magnitude and just need to set sign if(offset >= 0) { //positive sign coord[cind] = (HashEntry->coord[cind] + offset)%EnvROBARMCfg.anglevals[cind]; } else { //negative sign coord[cind] = (HashEntry->coord[cind] + offset); if(HashEntry->coord[cind] < -offset) coord[cind] = HashEntry->coord[cind] + EnvROBARMCfg.anglevals[cind] + offset; //if(coord[cind] < 0) //{ // printf("ERROR: ROBARM_LONGACTIONDIST_CELLS is too large for dim %d\n", cind); // exit(1); //} } }//else random offset }//over coordinates //skip the invalid sample if(!IsValidCoord(coord)) continue; //clock_t currenttime = clock(); //compute end effector ComputeContAngles(coord, angles); ComputeEndEffectorPos(angles, &endeffx, &endeffy); //skip the ones whose end-effector is outside if(abs(HashEntry->endeffx - endeffx) > ROBARM_LONGACTIONDIST_CELLS || abs(HashEntry->endeffy - endeffy) > ROBARM_LONGACTIONDIST_CELLS) continue; bool bIsGoal = false; if(endeffx == EnvROBARMCfg.EndEffGoalX_c && endeffy == EnvROBARMCfg.EndEffGoalY_c) { bIsGoal = true; //printf("goal succ is generated\n"); } EnvROBARMHashEntry_t* OutHashEntry = NULL; if((OutHashEntry = GetHashEntry(coord, NUMOFLINKS, bIsGoal)) == NULL) { //have to create a new entry OutHashEntry = CreateNewHashEntry(coord, NUMOFLINKS, endeffx, endeffy); } //compute clow int clow; clow = EnvironmentROBARM::GetFromToHeuristic(HashEntry->stateID, OutHashEntry->stateID); SuccIDV->push_back(OutHashEntry->stateID); CLowV->push_back(clow); //time3_addallout += clock()-currenttime; } //see if the goal belongs to the inside area and if yes then add it to SUCCS as well if(abs(EnvROBARMCfg.EndEffGoalX_c - HashEntry->endeffx) <= ROBARM_LONGACTIONDIST_CELLS && abs(EnvROBARMCfg.EndEffGoalY_c - HashEntry->endeffy) <= ROBARM_LONGACTIONDIST_CELLS) { EnvROBARMHashEntry_t* OutHashEntry = EnvROBARM.goalHashEntry; int clow = EnvironmentROBARM::GetFromToHeuristic(HashEntry->stateID, OutHashEntry->stateID); SuccIDV->push_back(OutHashEntry->stateID); CLowV->push_back(clow); } }
void EnvironmentROBARM::GetSuccs(int SourceStateID, vector<int>* SuccIDV, vector<int>* CostV) { int i, inc; short unsigned int succcoord[NUMOFLINKS]; double angles[NUMOFLINKS]; //clear the successor array SuccIDV->clear(); CostV->clear(); //goal state should be absorbing if(SourceStateID == EnvROBARM.goalHashEntry->stateID) return; //get X, Y for the state EnvROBARMHashEntry_t* HashEntry = EnvROBARM.StateID2CoordTable[SourceStateID]; //default coords of successor for(i = 0; i < NUMOFLINKS; i++) succcoord[i] = HashEntry->coord[i]; //iterate through successors of s for (i = 0; i < NUMOFLINKS; i++) { //increase and decrease in ith angle for(inc = -1; inc < 2; inc = inc+2) { if(inc == -1) { if(HashEntry->coord[i] == 0) succcoord[i] = EnvROBARMCfg.anglevals[i]-1; else succcoord[i] = HashEntry->coord[i] + inc; } else { succcoord[i] = (HashEntry->coord[i] + inc)% EnvROBARMCfg.anglevals[i]; } //skip invalid successors if(!IsValidCoord(succcoord)) continue; //get the successor EnvROBARMHashEntry_t* OutHashEntry; bool bSuccisGoal = false; short unsigned int endeffx = 0, endeffy = 0; bool bEndEffComputed = false; if(abs(HashEntry->endeffx - EnvROBARMCfg.EndEffGoalX_c) < 3 || abs(HashEntry->endeffy - EnvROBARMCfg.EndEffGoalY_c) < 3) { //do a strict checks on the endeff coordinates of the successor ComputeContAngles(succcoord, angles); ComputeEndEffectorPos(angles, &endeffx, &endeffy); if(endeffx == EnvROBARMCfg.EndEffGoalX_c && endeffy == EnvROBARMCfg.EndEffGoalY_c) { bSuccisGoal = true; //printf("goal succ is generated\n"); } bEndEffComputed = true; } if((OutHashEntry = GetHashEntry(succcoord, NUMOFLINKS, bSuccisGoal)) == NULL) { if(bEndEffComputed == false) { ComputeContAngles(succcoord, angles); ComputeEndEffectorPos(angles, &endeffx, &endeffy); } //have to create a new entry OutHashEntry = CreateNewHashEntry(succcoord, NUMOFLINKS, endeffx, endeffy); } SuccIDV->push_back(OutHashEntry->stateID); CostV->push_back(cost(HashEntry->coord,succcoord)); } //restore it back succcoord[i] = HashEntry->coord[i]; } }
static int CheckIfAllFilesKnown(TMPQArchive * ha, const char * szListFile, DWORD * pFileSeeds) { TMPQHash * pHashTableCopy = NULL; // Copy of the hash table TMPQHash * pHash; TMPQHash * pHashEnd = NULL; // End of the hash table DWORD dwFileCount = 0; int nError = ERROR_SUCCESS; // First of all, create a copy of hash table if(nError == ERROR_SUCCESS) { if((pHashTableCopy = CopyHashTable(ha)) == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; pHashEnd = pHashTableCopy + ha->pHeader->dwHashTableSize; // Notify the user if(CompactCB != NULL) CompactCB(lpUserData, CCB_CHECKING_FILES, 0, ha->pHeader->dwBlockTableSize); } // Now check all the files from the filelist if(nError == ERROR_SUCCESS) { SFILE_FIND_DATA wf; HANDLE hFind = SFileFindFirstFile((HANDLE)ha, "*", &wf, szListFile); BOOL bResult = TRUE; // Do while some files have been found while(hFind != NULL && bResult) { TMPQHash * pHash = GetHashEntry(ha, wf.cFileName); // If the hash table entry has been found, find it's position // in the hash table copy if(pHash != NULL) { pHash = pHashTableCopy + (pHash - ha->pHashTable); if(pHash->dwName1 != (DWORD)-1 && pHash->dwName2 != (DWORD)-1) { TMPQBlock * pBlock = ha->pBlockTable + pHash->dwBlockIndex; DWORD dwSeed = 0; // Resolve the file seed. Use plain file name for it if(pBlock->dwFlags & MPQ_FILE_ENCRYPTED) { char * szFileName = strrchr(wf.cFileName, '\\'); if(szFileName == NULL) szFileName = wf.cFileName; else szFileName++; dwSeed = DecryptFileSeed(szFileName); if(pBlock->dwFlags & MPQ_FILE_FIXSEED) dwSeed = (dwSeed + pBlock->dwFilePos) ^ pBlock->dwFSize; } pFileSeeds[pHash->dwBlockIndex] = dwSeed; pHash->dwName1 = 0xFFFFFFFF; pHash->dwName2 = 0xFFFFFFFF; pHash->lcLocale = 0xFFFF; pHash->wPlatform = 0xFFFF; pHash->dwBlockIndex = 0xFFFFFFFF; } } // Notify the user if(CompactCB != NULL) CompactCB(lpUserData, CCB_CHECKING_FILES, ++dwFileCount, ha->pHeader->dwBlockTableSize); // Find the next file in the archive bResult = SFileFindNextFile(hFind, &wf); } if(hFind != NULL) SFileFindClose(hFind); } // When the filelist checking is complete, parse the hash table copy and find the if(nError == ERROR_SUCCESS) { // Notify the user about checking hash table dwFileCount = 0; if(CompactCB != NULL) CompactCB(lpUserData, CCB_CHECKING_HASH_TABLE, dwFileCount, ha->pHeader->dwBlockTableSize); for(pHash = pHashTableCopy; pHash < pHashEnd; pHash++) { // If there is an unresolved entry, try to detect its seed. If it fails, // we cannot complete the work if(pHash->dwName1 != (DWORD)-1 && pHash->dwName2 != (DWORD)-1) { HANDLE hFile = NULL; DWORD dwFlags = 0; DWORD dwSeed = 0; if(SFileOpenFileEx((HANDLE)ha, (char *)(DWORD_PTR)pHash->dwBlockIndex, SFILE_OPEN_BY_INDEX, &hFile)) { TMPQFile * hf = (TMPQFile *)hFile; dwFlags = hf->pBlock->dwFlags; dwSeed = hf->dwSeed1; SFileCloseFile(hFile); } // If the file is encrypted, we have to check // If we can apply the file decryption seed if(dwFlags & MPQ_FILE_ENCRYPTED && dwSeed == 0) { nError = ERROR_CAN_NOT_COMPLETE; break; } // Remember the seed pFileSeeds[pHash->dwBlockIndex] = dwSeed; // Notify the user if(CompactCB != NULL) CompactCB(lpUserData, CCB_CHECKING_HASH_TABLE, ++dwFileCount, ha->pHeader->dwBlockTableSize); } } } // Delete the copy of hash table if(pHashTableCopy != NULL) FREEMEM(pHashTableCopy); return nError; }
bool Hashtable::ContainsKey(const void *key) { return GetHashEntry(key) ? true : false; }
void *Hashtable::GetValue(const void *key) { Entry *entry = GetHashEntry(key); return entry ? entry->value : NULL; }