/* * Trims the list of possible jump moves, so it only contains moves that result in the maximum amount of captures * * @params: (jumpMovesList) - the list of all possible jump moves * @return: a trimmed list, or NULL if any allocation errors occurred */ static struct LinkedList* trimJumpMovesList (struct LinkedList* jumpMovesList){ int maxCaptures = 0; //finding the maximum number of captures in a currently possible jump move struct Iterator iterator; Iterator_init(&iterator, jumpMovesList); while(Iterator_hasNext(&iterator)){ struct PossibleMove* currMove = (struct PossibleMove*)(Iterator_next(&iterator)); int currNumOfCaptures = PossibleMove_numOfCaptures(currMove); if(currNumOfCaptures > maxCaptures){ maxCaptures = currNumOfCaptures; } } //creating a new list and filling it only with the appropriate moves struct LinkedList* trimmedJumpMoves = LinkedList_new(&PossibleMove_free); if(trimmedJumpMoves == NULL){ // allocation failed return NULL; } struct Iterator secondIterator; Iterator_init(&secondIterator, jumpMovesList); while(Iterator_hasNext(&secondIterator)){ struct PossibleMove* currMove = (struct PossibleMove*)(Iterator_next(&secondIterator)); if(PossibleMove_numOfCaptures(currMove) == maxCaptures){ struct PossibleMove* clonedCurrMove = PossibleMove_clone(currMove); if (clonedCurrMove == NULL){ // allocation failed LinkedList_free(trimmedJumpMoves); return NULL; } LinkedList_add(trimmedJumpMoves, clonedCurrMove); } } LinkedList_free(jumpMovesList); return trimmedJumpMoves; }
//look up holder void testCommitTake(void) { //start a txn OESTORE_TXN oetxn; int ret = OeStore_start_txn(store, 10000, &oetxn, arena); assert(ret == 0); OeStoreHolder holder; ret = take1(oetxn.tid, &holder, "txn_one"); DataObject data = OeStoreHolder_get_data(holder); assert(!ret); assert(strcmp(DataObject_get_bytes( data ), "txn_nonesense") == 0); Iterator iter = DataObject_iterator(data, true); Iterator_next(iter);//0 assert(strcmp(Iterator_next( iter ), "txn_one") == 0); //make sure it isn't visible anymore OeStoreHolder holder2; ret = get1( &holder2, "txn_one"); assert(ret == OE_STORE_ITEM_NOTFOUND); //commit the txn ret = OeStore_update_txn(store, oetxn.tid, 0, OESTORE_TXN_COMMITTED, arena, -1); assert(ret == 0); //make sure it IS STILL not visible after commit of take OeStoreHolder holder3; ret = get1( &holder3, "txn_one"); assert(ret == OE_STORE_ITEM_NOTFOUND); }
void testTxnCommitPut(void) { //start a txn OESTORE_TXN oetxn; int ret = OeStore_start_txn(store, 10000, &oetxn, arena); assert(ret == 0); assert(oetxn.tid > 0); ret = put1(oetxn.tid, OESTORE_WRITE_LOCK, "txn_one"); if (ret) { OE_ERR(NULL, "put1 failed: %s\n", db_strerror(ret)); } assert(ret == 0); //make sure it isn't visible yet OeStoreHolder holder2; ret = get1(&holder2, "txn_one"); assert(ret == OE_STORE_ITEM_NOTFOUND); //commit the txn ret = OeStore_update_txn(store, oetxn.tid, 0, OESTORE_TXN_COMMITTED, arena, -1); OE_ERR(NULL, "upt failed: %s\n", db_strerror(ret)); assert(ret == 0); //make sure it IS visible now OeStoreHolder holder3; ret = get1(&holder3, "txn_one"); DataObject data3 = OeStoreHolder_get_data(holder3); OE_ERR(NULL, "get1 failed: %s\n", db_strerror(ret)); assert(!ret); Iterator iter = DataObject_iterator(data3, true); Iterator_next(iter);//0 assert(strcmp(Iterator_next( iter), "txn_one") == 0); }
// read/modify/write void testCommitRMW(void) { //save new test data int ret = put1(0, OESTORE_UNLOCKED, "three"); assert(ret == 0); //start a txn OESTORE_TXN oetxn; ret = OeStore_start_txn(store, 10000, &oetxn, arena); assert(ret == 0); //take the new data OeStoreHolder holder; ret = take1(oetxn.tid, &holder, "three"); DataObject data = OeStoreHolder_get_data(holder); assert(!ret); Iterator iter = DataObject_iterator(data, true); assert(strcmp(Iterator_next( iter ), "key") == 0); assert(strcmp(Iterator_next( iter ), "three") == 0); assert(strcmp(DataObject_get_bytes( data ), "txn_nonesense") == 0); //make sure it isn't visible anymore OeStoreHolder holder2 = NULL; ret = get1( &holder2, "three"); assert(ret == OE_STORE_ITEM_NOTFOUND); //put the replacement item into the space ret = put1(oetxn.tid, OESTORE_WRITE_LOCK, "four"); assert(!ret); //commit the txn ret = OeStore_update_txn(store, oetxn.tid, 0, OESTORE_TXN_COMMITTED, arena, 1); //wrong enlisted count assert(ret); ret = OeStore_update_txn(store, oetxn.tid, 0, OESTORE_TXN_COMMITTED, arena, 2);//right enlisted count assert(!ret); //make sure four IS visible after commit OeStoreHolder holder3; OeStore_start_txn(store, 10000, &oetxn, arena); ret = take1(oetxn.tid, &holder3, "four"); //and clean up for next tests... DataObject data3 = OeStoreHolder_get_data(holder3); OeStore_update_txn(store, oetxn.tid, 0, OESTORE_TXN_COMMITTED, arena, -1); assert(!ret); iter = DataObject_iterator(data3, true); assert(strcmp(Iterator_next( iter ), "key") == 0); assert(strcmp(Iterator_next( iter ), "four") == 0); assert(strcmp(DataObject_get_bytes( data3 ), "txn_nonesense") == 0); //make sure three is NOT visible OeStoreHolder holder4; ret = get1(&holder4, "three"); assert(ret == OE_STORE_ITEM_NOTFOUND); }
void testTakeOne(void *dummy) { Arena_T arena = Arena_new(); const int MAX_RESULTS = 1; DataObjectList keylists = DataObjectList_new(arena); DataObject keys = DataObjectList_new_data_object(keylists); DataObject_add_attr(keys, "key2"); DataObject_add_attr(keys, "seeme2three"); OeStoreHolder results[MAX_RESULTS + 1]; memset(results, 0, sizeof *results); size_t result_count = 0; OeStoreQuery query = OeStoreQuery_new(arena, MAX_RESULTS); OeStoreQuery_set_take(query, true); OeStoreQuery_set_tuple(query, false); OeStoreQuery_set_ifexists(query, false); OeStoreQuery_set_value_lists(query, keylists); int ret; while ( ( ret = OeStore_get(store, query) ) ) { if (ret == OE_STORE_PLEASE_RETRY) { printf("take one retry for deadlock\n"); OeStoreQuery_reset_nitems_found(query); continue; } if (ret == OE_STORE_ITEM_NOTFOUND) continue; result_count = OeStoreQuery_get_nitems_found(query); if (result_count == 0) continue; } assert(!ret); assert(result_count = 1); OeStoreHolder result = OeStoreQuery_get_store_holder(query, 0); DataObject data = OeStoreHolder_get_data(result); Iterator iter = DataObject_iterator(data, true); //Iterator iter = DataObject_iterator(data, false); printf("take result key1: %s\n", (char *) Iterator_next(iter)); //0 printf("take result val1: %s\n", (char *) Iterator_next(iter)); //1 printf("take result key2: %s\n", (char *) Iterator_next(iter)); //0 assert(strcmp(Iterator_next(iter), "seeme2three") == 0); assert(strcmp(DataObject_get_bytes(data), "nonesense") == 0); assert(OeStoreHolder_get_lock(result) == OESTORE_TAKE_LOCK); Arena_dispose(&arena); }
void Function_clearFunctionCache(void) { Entry entry; HashMap oldMap = s_funcMap; Iterator itor = Iterator_create(oldMap); s_funcMap = HashMap_create(59, TopMemoryContext); while((entry = Iterator_next(itor)) != 0) { Function func = (Function)Entry_getValue(entry); if(func != 0) { if(Function_inUse(func)) { /* This is the replace_jar function or similar. Just * move it to the new map. */ HashMap_put(s_funcMap, Entry_getKey(entry), func); } else { Entry_setValue(entry, 0); PgObject_free((PgObject)func); } } } PgObject_free((PgObject)itor); PgObject_free((PgObject)oldMap); }
/* all is an Oec_AList of DataObject entries */ oe_id Oed_Dispatcher_reg_group(T _this_, DataObjectList all, oe_time dur, bool consume, user_callback *match_handler, user_callback *timeout_handler, user_callback_arg args) { oe_id sid = 0; assert(all); List_T group = List_list(NULL); for (Iterator iter = DataObjectList_iterator(all, true); Iterator_hasMore(iter);) { DataObject o = Iterator_next(iter); oe_scalar *templ_p = DataObject_toArray(o); item_ *item = _create_reg_item(_this_, templ_p, dur, consume, match_handler, timeout_handler, args); sid = item->sid; group = List_append(group, List_list(item, NULL)); } item_ **groupitems = (item_**) List_toArray(group, NULL); for (int i = 0; i < List_length(group); i++) { groupitems[i]->group = group; _schedule_item(_this_, groupitems[i]); } Mem_free(groupitems, __FILE__, __LINE__); return sid; //you can cancel the whole group by unreg'ing this one sid }
/* * Updates a board according to a possible move. * * @params: (move) - the move to be carried out on the board */ void Board_update(char** board, struct PossibleMove* move){ struct Tile* current = move->start; struct LinkedList* steps = move->steps; struct Iterator iterator; Iterator_init(&iterator, steps); while(Iterator_hasNext(&iterator)){ struct Tile* dest = (struct Tile*)Iterator_next(&iterator); Board_move(board, current->x, current->y, dest->x, dest->y); current = dest; } }
int printBestMoves(char* command){ int depth; if (command[15] == 'b'){ depth = computeBestDepth(); } else{ if (sscanf(command, "get_best_moves %d", &depth) != 1){ return -1; } } LinkedList* allPossibleMoves = Board_getPossibleMoves(&board, turn); if (!allPossibleMoves){ return 1; } int bestScore = INT_MIN; Iterator iterator; Iterator_init(&iterator, allPossibleMoves); LinkedList* bestMoves = PossibleMoveList_new(); if (!bestMoves){ PossibleMoveList_free(allPossibleMoves); return 1; } while(Iterator_hasNext(&iterator)){ PossibleMove* currentMove = (PossibleMove*)Iterator_next(&iterator); int score = alphabeta(currentMove, depth, !turn, INT_MIN, INT_MAX); if (score > bestScore) { LinkedList_removeAll(bestMoves); if(LinkedList_add(bestMoves, currentMove)){ LinkedList_removeAll(bestMoves); LinkedList_free(bestMoves); PossibleMoveList_free(allPossibleMoves); return 1; } bestScore = score; } else if (score == bestScore){ if(LinkedList_add(bestMoves, currentMove)){ LinkedList_removeAll(bestMoves); LinkedList_free(bestMoves); PossibleMoveList_free(allPossibleMoves); return 1; } } } PossibleMoveList_print(bestMoves); LinkedList_removeAll(bestMoves); //removes the nodes LinkedList_free(bestMoves); //frees the struct LinkedList_free(allPossibleMoves); //frees the moves return 0; }
//delete holder and object (take) void testRollback(void) { //save new test data int ret = put1(0, OESTORE_UNLOCKED, "txn_two"); assert(ret == 0); //start a txn OESTORE_TXN oetxn; ret = OeStore_start_txn(store, 10000, &oetxn, arena); assert(ret == 0); OeStoreHolder holder; ret = take1(oetxn.tid, &holder, "txn_two"); DataObject data = OeStoreHolder_get_data(holder); assert(!ret); assert(holder); assert(strcmp(DataObject_get_bytes( data ), "txn_nonesense") == 0); Iterator iter = DataObject_iterator(data, true); Iterator_next(iter); //0 assert(strcmp(Iterator_next( iter ), "txn_two") == 0); //make sure it isn't visible anymore OeStoreHolder holder2; ret = get1(&holder2, "txn_two"); OE_ERR(NULL, "get1: %s\n", db_strerror(ret)); assert(ret == OE_STORE_ITEM_NOTFOUND); ret = take1(0, &holder2, "txn_two"); OE_ERR(NULL, "take1: %s\n", db_strerror(ret)); assert(ret == OE_STORE_ITEM_NOTFOUND); //rollback the txn ret = OeStore_update_txn(store, oetxn.tid, 0, OESTORE_TXN_ROLLED_BACK, arena, -1); OE_ERR(NULL, "updatetxn: %s\n", db_strerror(ret)); assert(ret == 0); //make sure it IS visible again after rollback of take OeStoreHolder holder4; ret = get1(&holder4, "txn_two"); DataObject data4 = OeStoreHolder_get_data(holder4); OE_ERR(NULL, "get1: %s\n", db_strerror(ret)); assert(!ret); iter = DataObject_iterator(data4, true); Iterator_next(iter); //0 assert(strcmp(Iterator_next( iter ), "txn_two") == 0); OeStoreHolder holder3 = NULL; OeStore_start_txn(store, 10000, &oetxn, arena); ret = take1(oetxn.tid, &holder3, "txn_two"); //and clean up for next tests... DataObject data3 = OeStoreHolder_get_data(holder3); OE_ERR(NULL, "take1: %s\n", db_strerror(ret)); assert(!ret); iter = DataObject_iterator(data3, true); Iterator_next(iter); //0 assert(strcmp(Iterator_next( iter ), "txn_two") == 0); OeStore_update_txn(store, oetxn.tid, 0, OESTORE_TXN_COMMITTED, arena, 1); }
PossibleMove* getBestMove(){ LinkedList* allPossibleMoves = Board_getPossibleMoves(&board, turn); if (!allPossibleMoves){ return NULL; } int depth = getDepth(); int bestScore = INT_MIN; PossibleMove* bestMove; Iterator iterator; Iterator_init(&iterator, allPossibleMoves); while(Iterator_hasNext(&iterator)){ PossibleMove* currentMove = (PossibleMove*)Iterator_next(&iterator); int score = alphabeta(currentMove, depth, !turn, INT_MIN, INT_MAX); if (score > bestScore || (score == bestScore && rand()%2)) { bestScore = score; bestMove = currentMove; } } LinkedList_freeAllButOne(allPossibleMoves, bestMove); return bestMove; }
/* * The minimax AI algorithm. */ int alphabeta(PossibleMove* possibleMove, int depth, int player, int alpha, int beta){ int (*evaluationFunction)(Board*, int, int) = (maxRecursionDepth == BEST)? &Board_getBetterScore: &Board_getScore; int thisBoardScore = evaluationFunction(possibleMove->board, turn, player); // maximum depth reached or game is over or allocation error occurred in Board_getScore if (depth == 1 || thisBoardScore == 10000 || thisBoardScore == -10000 || thisBoardScore == -10001){ return thisBoardScore; } Board* board = possibleMove->board; LinkedList* possibleMoves = Board_getPossibleMoves(board, player); if (!possibleMoves){ return -10001; } //terminal node if (LinkedList_length(possibleMoves) == 0){ LinkedList_free(possibleMoves); return thisBoardScore; } //single child node if (LinkedList_length(possibleMoves) == 1){ PossibleMove* onlyMove = PossibleMoveList_first(possibleMoves); int score = evaluationFunction(onlyMove->board, turn, player); LinkedList_free(possibleMoves); return score; } int extremum = (player == turn)? INT_MIN : INT_MAX; Iterator iterator; Iterator_init(&iterator, possibleMoves); while (Iterator_hasNext(&iterator)) { PossibleMove* currentPossibleMove = (PossibleMove*)Iterator_next(&iterator); int score = alphabeta(currentPossibleMove, depth-1, !player, alpha, beta); if (score == -10001){ //allocation error occured extremum = score; break; } if ( (player != turn && score < extremum) || (player == turn && score > extremum) || (rand()%2 && score == extremum) ){ extremum = score; } //game over - no need to evaluate further moves // if (extremum == 10000 || extremum == -10000){ // break; // } //alpha-beta pruning if (turn == player){ alpha = (score > alpha)? score: alpha; if (alpha >= beta){ break; } } else{ beta = (score < beta)? score: beta; if (beta <= alpha){ break; } } } LinkedList_free(possibleMoves); return extremum; }