// Check if the page is on the free list. Requires traversing the link list // More efficient data structures are possible! const Status File::onFreeList(const int pageNo, bool& onFL) const { int pgNo; Page header; Status status; onFL = false; if ((status = intread(0, &header)) != OK) return status; // Check the free list pages if (DBP(header).nextFree != -1) // Free list exists { while ((pgNo = DBP(header).nextFree) != -1) { if (pageNo == pgNo) { onFL = true; return OK; } // Read the next page; if ((status = intread(pgNo, &header)) != OK) return status; } } return OK; }
const Status File::create(const string & fileName) { int file; if ((file = ::open(fileName.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0666)) < 0) { if (errno == EEXIST) return FILEEXISTS; else return UNIXERR; } // An empty file contains just a DB header page. Page header; memset(&header, 0, sizeof header); DBP(header).nextFree = -1; DBP(header).firstPage = -1; DBP(header).numPages = 1; if (write(file, (char*)&header, sizeof header) != sizeof header) return UNIXERR; if (::close(file) < 0) return UNIXERR; return OK; }
parser_state * PyParser_New(grammar *g, int start) { parser_state *ps; DBP("Attempting to create new PyParser\n"); if (!g->g_accel) PyGrammar_AddAccelerators(g); DBP("Added grammar accelerators\n"); ps = (parser_state *)PyMem_MALLOC(sizeof(parser_state)); DBP("Created parser state\n"); if (ps == NULL) return NULL; ps->p_grammar = g; #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD ps->p_flags = 0; #endif ps->p_tree = PyNode_New(start); if (ps->p_tree == NULL) { PyMem_FREE(ps); return NULL; } s_reset(&ps->p_stack); (void) s_push(&ps->p_stack, PyGrammar_FindDFA(g, start), ps->p_tree); DBP("Created PyParser!!\n"); return ps; }
void testLazyFailureFunctionRandom(std::string const & pattern) { ::libmaus::autoarray::AutoArray<int64_t> BP = ::libmaus::util::KMP::BEST_PREFIX(pattern.begin(),pattern.size()); ::libmaus::random::Random::setup(); for ( uint64_t i = 0; i < 16*1024*1024; ++i ) { std::istringstream pistr(pattern); ::libmaus::util::KMP::BestPrefix<std::istream> DBP(pistr,pattern.size()); std::vector<uint64_t> probes; for ( uint64_t j = 0; j < 2*pattern.size(); ++j ) probes.push_back( ::libmaus::random::Random::rand64() % (BP.size()) ); #if 0 for ( uint64_t i = 0; i < probes.size(); ++i ) std::cerr << BP[probes[i]] << ";"; std::cerr << std::endl; #endif for ( uint64_t i = 0; i <= pattern.size(); ++i ) { assert ( DBP[probes[i]] == BP[probes[i]] ); #if 0 std::cerr << DBP[probes[i]] << ";"; #endif } #if 0 std::cerr << std::endl; #endif } }
const Status File::getFirstPage(int& pageNo) const { Page header; Status status; if ((status = intread(0, &header)) != OK) return status; pageNo = DBP(header).firstPage; return OK; }
void DBPt(const char *fmt, ...) { char *Str; va_list vlist; Str = malloc(1024); va_start(vlist, fmt); vsprintf(Str, fmt, vlist); va_end(vlist); DBP("%s", Str); }
// Deallocate a page from file. The page will be put on a free // list and returned back to the caller upon a subsequent // allocPage() call. // ALERT: No error returned if disposePage called on the same page twice! const Status File::disposePage(int pageNo) { if (pageNo < 1) return BADPAGENO; Page header; Status status; if ((status = intread(0, &header)) != OK) return status; // The first user-allocated page in the file cannot be // disposed of. The File layer has no knowledge of what // is the next page in the file and hence would not be // able to adjust the firstPage field in file header. if (DBP(header).firstPage == pageNo || pageNo >= DBP(header).numPages) return BADPAGENO; // Deallocate page by attaching it to the free list. Page away; if ((status = intread(pageNo, &away)) != OK) return status; memset(&away, 0, sizeof away); DBP(away).nextFree = DBP(header).nextFree; DBP(header).nextFree = pageNo; if ((status = intwrite(pageNo, &away)) != OK) return status; if ((status = intwrite(0, &header)) != OK) return status; #ifdef DEBUGFREE listFree(); #endif return OK; }
const Status File::allocatePage(int& pageNo) { Page header; Status status; if ((status = intread(0, &header)) != OK) return status; // If free list has pages on it, take one from there // and adjust free list accordingly. if (DBP(header).nextFree != -1) { // free list exists? // Return first page on free list to the caller, // adjust free list accordingly. pageNo = DBP(header).nextFree; Page firstFree; if ((status = intread(pageNo, &firstFree)) != OK) return status; DBP(header).nextFree = DBP(firstFree).nextFree; } else { // no free list, have to extend file // Extend file -- the current number of pages will be // the page number of the page to be returned. pageNo = DBP(header).numPages; Page newPage; memset(&newPage, 0, sizeof newPage); if ((status = intwrite(pageNo, &newPage)) != OK) return status; DBP(header).numPages++; if (DBP(header).firstPage == -1) // first user page in file? DBP(header).firstPage = pageNo; } if ((status = intwrite(0, &header)) != OK) return status; #ifdef DEBUGFREE listFree(); #endif return OK; }
void File::listFree() { cerr << "%% File " << (int)this << " free pages:"; int pageNo = 0; for(int i = 0; i < 10; i++) { Page page; if (intread(pageNo, &page) != OK) break; pageNo = DBP(page).nextFree; cerr << " " << pageNo; if (pageNo == -1) break; } cerr << endl; }