HASH_NODE *hashInsert(char *str, int type) { int address; HASH_NODE *newNode; // if it is a string or char, we should strip it before anything else if(type == LIT_STRING || type == LIT_CHAR) { str++; str[strlen(str) - 1] = '\0'; } // "str" is already on hashtable if((newNode = hashFind(str, type))) return newNode; // new node allocation if(!(newNode = (HASH_NODE *) malloc(sizeof(HASH_NODE))) || !(newNode->text = (char *) malloc(sizeof(char) * strlen(str)))) { fprintf(stderr, "Error: out of memory\n"); exit(1); // abort? } newNode->type = type; strncpy(newNode->text, str, strlen(str)); address = hashAddress(str); newNode->next = _symbolTable[address]; _symbolTable[address] = newNode; return newNode; }
// Given a function pointer and a name, inserts a new entry into the hashtable // Will not allow the same entry to be inserted twice. int hashInsert( HashTable * tab, char * entry, void ( * ( f ) )( void * ) ){ hEntry * newFunc; hEntry * curFunc; unsigned int index = hash( entry, tab->size ); if( ( newFunc = calloc( 1, sizeof( hEntry ) ) ) == NULL ){ fprintf( stderr, "Error mallocing new node. \n" ); return 1; } curFunc = hashFind( tab, entry ); if( curFunc != NULL ){ fprintf( stderr, "Function is already in registry.\n" ); return 2; } newFunc->name = strdup( entry ); newFunc->func = f; newFunc->next = tab->table[ index ]; tab->table[ index ] = newFunc; return 0; }
int calcDiff(calc_ *r, char *variable, double *solution) { tokenSolveArgs_ args; ReturnErrIf(r == NULL); ReturnErrIf(solution == NULL); ReturnErrIf(variable == NULL); args.parser = r->parser; args.solution = solution; ReturnErrIf(hashFind(r->variables, variable, (void*)&args.diffVariable)); ReturnErrIf(args.diffVariable == NULL, "Couldn't find variable %s.", variable); /* Put Parser in differentiation mode */ Debug("%s", ParseTokenName(TOKEN_DIFF)); Parse(r->parser, TOKEN_DIFF, NULL, solution); ReturnErrIf(isnan(*solution), "Parser failed"); ReturnErrIf(listExecute(r->tokens, (listExecute_)tokenSolve, &args)); ReturnErrIf(isnan(*solution), "Parser failed"); return 0; }
HASH_NODE *hashInsert (HASH_TABLE *Table, char *text, int type, int lineNumber) { HASH_NODE *node; int address; // Check if the table is getting full and resize it if (Table->usedEntries > hash_i*HASH_SIZE/2) { hashResize(Table); } address = 0; node = hashFind(Table, text, type); // First check if it is in the hash if (node == 0) { address = hashAddress(Table, text); HASH_NODE *newNode; newNode = (HASH_NODE*)calloc(1, sizeof(HASH_NODE)); newNode -> type = type; newNode -> lineNumber = lineNumber; newNode -> text = (char*)calloc(sizeof(strlen(text)+1), sizeof(strlen(text)+1)); strcpy(newNode -> text, text); newNode -> next = Table -> node[address]; Table -> node[address] = newNode; Table -> usedEntries++; return newNode; } else { return node; } }
int ObjCache::add(void *obj,void **victim) { *victim=0; HashNode *hnode = hashFind(obj); //printf("hnode=%p\n",hnode); if (hnode) // move object to the front of the LRU list, since it is used // most recently { //printf("moveToFront=%d\n",hnode->index); moveToFront(hnode->index); m_hits++; } else // object not in the cache. { void *lruObj=0; if (m_freeCacheNodes!=-1) // cache not full -> add element to the cache { // remove element from free list int index = m_freeCacheNodes; m_freeCacheNodes = m_cache[index].next; // add to head of the list if (m_tail==-1) { m_tail = index; } m_cache[index].prev = -1; m_cache[index].next = m_head; if (m_head!=-1) { m_cache[m_head].prev = index; } m_head = index; m_count++; } else // cache full -> replace element in the cache { //printf("Cache full!\n"); lruObj = m_cache[m_tail].obj; hashRemove(lruObj); moveToFront(m_tail); // m_tail indexes the emptied element, which becomes m_head } //printf("numEntries=%d size=%d\n",m_numEntries,m_size); m_cache[m_head].obj = obj; hnode = hashInsert(obj); hnode->index = m_head; *victim = lruObj; m_misses++; } return m_head; }
HashNode* hashInsert(char* key, int type){ HashNode* node; int address = hashAddress(key); if( (node = hashFind(key)) != NULL ) return node; node = (HashNode*) malloc(sizeof(HashNode)); node->key = (char*) malloc(strlen(key)); strcpy(node->key, key); node->type = type; node->next = symbolTable[address]; symbolTable[address] = node; return node; }
Hash_Node* hashInsert(char *text, int token) { int address; if (hashFind(text) == NULL) { address = hashAddress(text); Hash_Node *node = calloc(1,sizeof(Hash_Node)); node->text = calloc(strlen(text), sizeof(char)); strcpy(node->text,text); node->type = token; node->next = table[address]; table[address] = node; return node; } else return NULL; }
void hashCollectPV(Position* position, Move pv[]){ HashData* hd; guint64 hData; guint index = 0; while(hashFind(&hd,position->key,&hData)){ if(index < Max_Pv-1 && hashMove(hData) != Empty){ pv[index] = hashMove(hData); moveDo(position,pv[index]); index++; } else break; } pv[index] = Empty; while(index>0){ moveUndo(position); index--; } }
// If a function is registered, it will be enqueued for execution. // If the funciton cannot be found, an error is printed with the event name // IMPORTANT NOTE: In the produce loop of the stream, I have to lock // before caling this void announceEvent( void * handle, const char * eventName, void * info ){ Handle * hand = ( Handle * ) handle; HashTable * tab = hand->registry; EventQueue * que = hand->cue; hEntry * fin; if( ( fin = hashFind( tab, ( char * )eventName ) ) != NULL ){ qInsert( que, fin->func, info ); } else{ fprintf( stderr, "WARNING: UNHANDLED EVENT: %s\n", eventName ); } if( pthread_cond_signal( &hand->cv ) != 0 ){ fprintf( stderr, "Error in signal.\n" ); exit( - 1 ); } }
gint threadSearch(Position* position, gint alpha, gint beta, gint depth, gint hight, const gboolean nullMove, const gboolean nodePV){ Moves moves; Move move, bestMove = Empty, hMove = Empty, pMove=Empty; gboolean extend=FALSE, endGamePhase; gint eval, tmpDepth, movesSearched = 0, pAlpha, pType; guint idleThreads; guint64 key = position->key, hData; HashData* hd; if(stopFlag == TRUE && !ponderSearch) return EVAL_DRAW; searchNodes++; /* Draw */ if(positionRepeat(position) >= 1 || position->staticMoves >= 100) return EVAL_DRAW; /* End game */ gint numberOfPieces = numberOfBits64(position->allPieces); if(numberOfPieces <= 5 && egbbIsLoaded()){ tmpDepth = (2 * iterativeDepth) / 3; if((numberOfPieces <= 4 || hight <= tmpDepth) && (hight >= tmpDepth || positionEvalEG(position))){ if(egbbProbe(position, &eval)){ if(eval < 0) return eval + hight * 40 + positionMaterial(position); if(eval > 0) return eval - hight * 40 + positionMaterial(position); return eval; } } } /* Mate distance pruning */ eval = -EVAL_MATE + hight; if(eval > alpha){ if(eval >= beta) return eval; alpha = eval; } eval = EVAL_MATE - hight; if(eval < beta){ if(eval <= alpha) return eval; beta = eval; } /* Hash */ if(hashFind(&hd,key,&hData)){ hMove = hashMove(hData); if(!nodePV && (gint)hashDepth(hData) >= depth){ if(hashFlag(hData) == EXACT) return hashEval(hData); else if(hashFlag(hData) == ALPHA && hashEval(hData) > alpha){ bestMove = hashMove(hData); alpha = hashEval(hData); if(alpha >= beta) return alpha; } else if(hashFlag(hData) == BETA && hashEval(hData) < beta){ beta = hashEval(hData); if(alpha >= beta) return beta; } } } /* Extension */ if(position->extend || (nodePV && passedPawnMove(position))){ depth ++; extend = TRUE; } /* Horizon */ if(depth < 1){ eval = quiescent(position,alpha,beta,hight+1,TRUE); return eval; } if(position->phase <= 7 && numberOfPieces <= 10) endGamePhase = TRUE; else endGamePhase = FALSE; /* Null move pruning */ if (!nodePV && nullMove && depth>2 && !extend && !endGamePhase){ if(depth > 6) tmpDepth = depth - 4; else tmpDepth = depth - 3; moveDo(position,Null_Move); eval = -threadSearch(position,-beta,-beta+1,tmpDepth,hight+1,FALSE,FALSE); moveUndo(position); if(eval >= beta){ hashWrite(hd,key,depth,eval,ALPHA,Empty); return eval; } } /* Internal Iterative Deepening */ tmpDepth = depth/2; if(nodePV && hMove == Empty && depth > 3 && tmpDepth >= (gint)hashDepth(hData)){ threadSearch(position,alpha, beta, tmpDepth, hight, FALSE,nodePV); if(hashFind2(hd,key,&hData)) hMove = hashMove(hData); } /* First move */ moves.state = START; if(hMove != Empty){ move = hMove; moveDo(position,move); } else move = nextMoveDo(position,&moves); if(move != Empty){ eval = -threadSearch(position, -beta, -alpha, depth-1, hight+1, TRUE,nodePV); if(eval > alpha){ if(eval >= beta){ moveUndo(position); if(moves.state == STATIC) history[moveGetFrom(move)][moveGetTo(move)] += 1<<depth; hashWrite(hd,key,depth,eval,ALPHA,move); return eval; } alpha = eval; bestMove = move; } moveUndo(position); movesSearched ++; } /* Parallel search*/ idleThreads = searchThreads; while(TRUE){ if(idleThreads > 0){ move = nextMoveDo(position,&moves); /* Last moves searched sequential */ if(move == Empty){ parallelStopFlag = TRUE; moves.size = moves.next = 0; while(idleThreads != searchThreads){ parallelSearchResult(&pMove,&pAlpha,&pType); idleThreads++; moves.move[moves.size] = pMove; moves.size ++; } parallelStopFlag = FALSE; moves.toSort = moves.size; break; } /* History pruning */ if(!nodePV && movesSearched >= HistoryFullDepthMoves && depth > HistoryReductionLimit && !extend && !position->extend){ idleThreads--; parallelSearch(position, move, -(alpha+1), -alpha, depth-2, hight+1,TRUE,HP,FALSE); moveUndo(position); movesSearched ++; } else{ /* PVS */ idleThreads--; parallelSearch(position, move, -(alpha+1), -alpha, depth-1, hight+1,TRUE,PVS,FALSE); moveUndo(position); movesSearched ++; } } else{ eval = -parallelSearchResult(&pMove,&pAlpha,&pType); idleThreads++; pAlpha = -pAlpha - 1; if(pType == HP && eval > pAlpha){ /* HP */ idleThreads--; moveDo(position,pMove); parallelSearch(position, pMove, -(pAlpha+1), -pAlpha, depth-1, hight+1,TRUE,PVS,FALSE); moveUndo(position); continue; } if(pType == PVS && eval > pAlpha && eval < beta){ /* PVS research */ idleThreads--; moveDo(position,pMove); parallelSearch(position, pMove, -beta, -pAlpha, depth-1, hight+1,TRUE,RPVS,nodePV); moveUndo(position); continue; } if(eval > alpha){ if(eval >= beta){ parallelSearchStop(idleThreads); if(moveGetType(pMove) == Normal) history[moveGetFrom(pMove)][moveGetTo(pMove)] += 1<<depth; hashWrite(hd,key,depth,eval,ALPHA,pMove); return eval; } alpha = eval; bestMove = pMove; } } } /* Last moves searched sequential */ move = nextMoveDo(position,&moves); while(move != Empty){ /* History pruning */ if(!nodePV && movesSearched >= HistoryFullDepthMoves && depth > HistoryReductionLimit && !extend && !position->extend){ eval = -threadSearch(position, -(alpha+1), -alpha, depth-2, hight+1, TRUE, FALSE); } else eval = alpha + 1; /* PVS */ if(eval > alpha){ eval = -threadSearch(position, -(alpha+1), -alpha, depth-1, hight+1, TRUE, FALSE); if(eval > alpha && eval < beta) eval = -threadSearch(position, -beta, -alpha, depth-1, hight+1, TRUE, nodePV); } moveUndo(position); if(eval > alpha){ if(eval >= beta){ if(moveGetType(pMove) == Normal) history[moveGetFrom(move)][moveGetTo(move)] += 1<<depth; hashWrite(hd,key,depth,eval,ALPHA,move); return eval; } alpha = eval; bestMove = move; } movesSearched ++; move = nextMoveDo(position,&moves); } /* Mate or pat */ if(movesSearched == 0){ if(position->inCheck == TRUE){ eval = -EVAL_MATE+hight; hashWrite(hd,key,depth,eval,EXACT,Empty); return eval; } else{ hashWrite(hd,key,depth,EVAL_DRAW,EXACT,Empty); return EVAL_DRAW; } } /* hash is update */ if(bestMove != Empty) hashWrite(hd,key,depth,alpha,EXACT,bestMove); else hashWrite(hd,key,depth,alpha,BETA,hMove); return alpha; }