int BookReader::lookup(const Board &board, vector<book::DataEntry> &results) { // fetch the index page if (!is_open()) return -1; int probe = (int)(board.hashCode() % hdr.num_index_pages); // seek to index book_file.seekg((std::ios::off_type)(sizeof(book::BookHeader)+probe*sizeof(book::IndexPage)), std::ios_base::beg); if (book_file.fail()) return -1; book::IndexPage index; book_file.read((char*)&index,sizeof(book::IndexPage)); if (book_file.fail()) return -1; // correct for endianness index.next_free = swapEndian32((byte*)&index.next_free); book::BookLocation loc(0,book::INVALID_INDEX); for (unsigned i = 0; i < index.next_free; i++) { // correct for endianness uint64_t indexHashCode = (uint64_t)(swapEndian64((byte*)&index.index[i].hashCode)); if (indexHashCode == board.hashCode()) { // correct for endianness index.index[i].page = (uint16_t)(swapEndian16((byte*)&index.index[i].page)); index.index[i].index = (uint16_t)(swapEndian16((byte*)&index.index[i].index)); loc = index.index[i]; break; } } if (!loc.isValid()) { // no book moves found return 0; } book_file.seekg(sizeof(book::BookHeader)+ hdr.num_index_pages*sizeof(book::IndexPage)+ loc.page*sizeof(book::DataPage)); if (book_file.fail()) return -1; book::DataPage data; book_file.read((char*)&data,sizeof(book::DataPage)); if (book_file.fail()) return -1; while(loc.index != book::NO_NEXT) { ASSERT(loc.index < book::DATA_PAGE_SIZE); book::DataEntry &bookEntry = data.data[loc.index]; bookEntry.next = swapEndian16((byte*)&bookEntry.next); bookEntry.weight = swapEndian16((byte*)&bookEntry.weight); bookEntry.count = swapEndian32((byte*)&bookEntry.count); results.push_back(bookEntry); loc.index = bookEntry.next; } return (int)results.size(); }
int BookWriter::write(const char* pathName) { ofstream book_file(pathName, ios::out | ios::trunc | ios::binary); book::BookHeader header; header.version = book::BOOK_VERSION; uint16_t pages = (uint16_t)index_pages; header.num_index_pages = (uint16_t)swapEndian16((byte*)&pages); book_file.write((char*)&header, sizeof(book::BookHeader)); if (book_file.fail()) return -1; book::IndexPage empty; for (int i = 0; i < index_pages; i++) { book::IndexPage *ip = (index[i] == NULL) ? &empty : index[i]; // correct for endianness before disk write for (unsigned j = 0; j < ip->next_free; j++) { ip->index[j].page = (uint16_t)swapEndian16((byte*)&ip->index[j].page); ip->index[j].index = (uint16_t)swapEndian16((byte*)&ip->index[j].index); ip->index[j].hashCode = (uint64_t)swapEndian64((byte*)&ip->index[j].hashCode); } ip->next_free = (uint32_t)swapEndian32((byte*)&ip->next_free); book_file.write((char*)ip, sizeof(book::IndexPage)); if (book_file.fail()) return -1; } for (unsigned i = 0; i < data.size(); i++) { book::DataPage *dp = data[i]; // correct for endianness before disk write dp->free_list = (uint32_t)swapEndian32((byte*)&dp->free_list); dp->num_free = (uint32_t)swapEndian32((byte*)&dp->num_free); for (int j = 0; j < book::DATA_PAGE_SIZE; j++) { dp->data[j].next = (uint16_t)swapEndian16((byte*)&dp->data[j].next); dp->data[j].weight = (uint16_t)swapEndian16((byte*)&dp->data[j].weight); dp->data[j].count = (uint32_t)swapEndian32((byte*)&dp->data[j].count); } book_file.write((char*)dp, sizeof(book::DataPage)); if (book_file.fail()) return -1; } book_file.close(); return 0; }