/*========================================= * check_index -- Validate one index node of btree * Created: 2003/09/05, Perry Rapp *=======================================*/ static BOOLEAN check_index (BTREE btr, INDEX index, TABLE fkeytab, RKEY * lo, RKEY * hi) { INT n = nkeys(index); INT i; if (!check_keys((BLOCK)index, lo, hi)) return FALSE; for (i = 0; i <= n; i++) { INDEX newix=0; char scratch[200]; FKEY fkey = fkeys(index, i); RKEY *lox, *hix; get_index_file(scratch, btr, fkey); if (in_table(fkeytab, scratch)) { printf(_("Cycle in indexes, file %s found again!\n"), scratch); return FALSE; } else { insert_table_int(fkeytab, scratch, 1); } newix = readindex(btr, fkey, TRUE); if (!newix) { printf(_("Error loading index at key")); printf("%ld\n", i); printblock((BLOCK)index); } /* figure upper & lower bounds of what keys should be in the child */ lox = (i==0 ? lo : &rkeys(index, i)); hix = (i==n ? hi : &rkeys(index, i+1)); if (ixtype(newix) == BTINDEXTYPE) { if (!check_index(btr, newix, fkeytab, lox, hix)) return FALSE; } else { if (!check_block((BLOCK)newix, lox, hix)) return FALSE; } } /* TODO: use fkeytab */ return TRUE; }
/*========================================= * check_keys -- Validate keys of index or block * Created: 2003/09/05, Perry Rapp *=======================================*/ static BOOLEAN check_keys (BLOCK block, RKEY * lo, RKEY * hi) { INT n = nkeys(block); INT i = 0; INT start = 0; BOOLEAN ok = TRUE; if (ixtype(block) == BTINDEXTYPE) ++start; /* keys are 1..n for index */ else --n; /* keys are 0..n-1 for block */ for (i=start ; i <= n; i++) { if (i==start && lo) { INT rel = cmpkeys(lo, &rkeys(block, i)); if (rel < 0) { printf(_("First key in block below parent's limit\n")); printblock(block); ok = FALSE; } } if (i==n && hi) { INT rel = cmpkeys(&rkeys(block, i), hi); if (rel > 0) { printf(_("Last key in block above parent's limit\n")); printblock(block); ok = FALSE; } } if (i<n) { INT rel = cmpkeys(&rkeys(block, i), &rkeys(block, i+1)); if (rel >= 0) { printf(_("Key not below next key")); printf(": %ld\n", i); printblock(block); ok = FALSE; } } } return ok; }
void __makeTasks__prev( string rule, string file, string target, TaskQueue* queue, OS* os, string& input, bool finalRule=false ) { os->pushString(rule.c_str()); os->pushValueById(rules->valueID); if(!os->in()) { cerr << "[IceTea]: " << rule << " does not exist."; return; } os->pushString(rule.c_str()); os->getProperty(); Value::Object myRule(os, os->getAbsoluteOffs(-1)); // Now get the two most important properties Value::Array* accepts = (Value::Array*)myRule["accepts"]; Value::Object* outputs = (Value::Object*)myRule["output"]; // Now create some strings. Value::String* o_myPattern = (Value::String*)(*outputs)["pattern"]; Value::String* o_myExpected = (Value::String*)(*outputs)["expected"]; string myPattern = (*o_myPattern); string myExpected = (*o_myExpected); // Clean up the heap delete outputs; delete o_myPattern; delete o_myExpected; // Replace stuff... string basename = PathToFileName(file.c_str()); string ext = StripFileExtension(basename); ReplaceStringInPlace(myExpected, "%t", target); ReplaceStringInPlace(myExpected, "%b", basename); ReplaceStringInPlace(myExpected, "%e", ext); ReplaceStringInPlace(myExpected, "%f", file); //cout <<rule<< " Working: " << file << " --> " << myExpected << endl; // Does the file we are processing actually HAVE a rule it can be run with, at all? os->pushValueById(rules->valueID); os->getProperty(-1, "keys"); Value::Array rkeys(os); bool hasARule=false; for(int r=0; r<rkeys.length(); r++) { Value::String* ruleName = (Value::String*)rkeys[r]; Value::Object* val = (Value::Object*)(*rules)[(*ruleName)]; Value::Array* rAccepts = (Value::Array*)(*val)["accepts"]; for(int o=0; o<rAccepts->length(); o++) { Value::String* rPat = (Value::String*)(*rAccepts)[o]; if(WildcardMatch(file.c_str(), (*rPat))) { hasARule=true; break; } } delete ruleName; delete val; } if(!hasARule) { cerr << "[IceTea]: It appears, that "<< file << " has no rule it can be ran with!" << " The file will be added verbatim. Be aware of this." << endl; return; } // Does the file we have, already match any pattern in the accept array? bool fits=false; for(int i=0; i<accepts->length(); i++) { Value::String* o_pat = (Value::String*)(*accepts)[i]; string pat = (*o_pat); //cout << "Comparing with: " << pat << endl; if(WildcardMatch(file.c_str(), pat.c_str())) { fits=true; break; } delete o_pat; } if(!fits) { //cout << "Finding new processor rule..." << endl; // Our file is not accepted by the rule. // So let's one that works and process it with that. // Problem is, a rule may have multiple accepts... // so we have to go over all of them and look for a rule. for(int j=0; j<accepts->length(); j++) { Value::String* o_pat = (Value::String*)(*accepts)[j]; string pat = (*o_pat); // Now we search up for the rule that HAS the pattern as its output pattern. // that also is why you only define an output pattern as STRING. os->pushValueById(rules->valueID); os->getProperty(-1, "keys"); // triggers the getKeys method. Value::Array keys(os); for(int e=0; e<keys.length(); e++) { Value::String* key = (Value::String*)keys[e]; Value::Object* val = (Value::Object*)(*rules)[(*key)]; Value::Object* v_output = (Value::Object*)(*val)["output"]; Value::String* v_pat = (Value::String*)(*v_output)["pattern"]; string sv_pat = (*v_pat); if( pat == sv_pat ) { //cout << "Comparing " << pat << " to " << sv_pat << " as " << (*key) << endl; // The current rule accepts input, from the found rule. // But does the found rule actually support our file? string n_rule = (*key); string t_input; __makeTasks(n_rule, file, target, queue, os, t_input); string inputFile = (!t_input.empty() ? t_input : file); // We are going to compare output pattern to accept pattern... // But we also must see if our file actually fits as accepted, for the rule we want the output //cout << "Testing rule: " << n_rule << " with: " << file << endl; cout << n_rule << ": " << file << ", " << inputFile << ", " << myExpected << endl; Value::Array* t_accepts = (Value::Array*)(*val)["accepts"]; bool isAccepted=false; for(int p=0; p<t_accepts->length(); p++) { Value::String* t_pat = (Value::String*)(*t_accepts)[p]; cout << "Trying: " << (*t_pat) << endl; if( WildcardMatch(inputFile.c_str(), (*t_pat)) ) { cout << "hit!" << endl; isAccepted=true; break; } delete t_pat; } delete t_accepts; delete key; delete val; delete v_output; delete v_pat; // Determine the "output" if(!finalRule) input = myExpected; else input = inputFile; // But we have to add this as a rule, since it was called that way. if(isAccepted) { if(!finalRule) { Task* t = new Task; t->ruleName = rule; t->targetName = target; t->input.push_back(inputFile); t->output = myExpected; // Find out what type the rule is. A function, or an array of commands? os->pushValueById(myRule.valueID); os->getProperty(-1, "build"); if(os->getTypeStr() == "array") { t->type=COMMAND; for(int k=0; k<os->getLen(); k++) { os->pushNumber(k); os->getProperty(); t->commands.push_back( os->popString().toChar() ); } } else if(os->getTypeStr() == "function") { t->type=SCRIPT; os->pushValueById(myRule.valueID); Value::Object* theRule = new Value::Object(os); t->onBuild = new Value::Method(os, theRule, "build"); } else { cerr << "[IceTea]: Rule '"<< rule << "' must have it's build property defined as function or array! " << "'" << os->getTypeStr() << "' was given instead." << endl; } t->target = (Value::Object*)(*targets)[target]; queue->add(t); return; // Nothing to return here. But we end the function here. } } } } } } else { cout << rule << " Input: " << file << endl; // file fits with out accepted entries! So we create a task and put it in. Task* t = new Task; t->ruleName = rule; t->targetName = target; t->input.push_back(file); t->output = myExpected; // Find out what type the rule is. A function, or an array of commands? os->pushValueById(myRule.valueID); os->getProperty(-1, "build"); if(os->getTypeStr() == "array") { t->type=COMMAND; for(int k=0; k<os->getLen(); k++) { os->pushNumber(k); os->getProperty(); t->commands.push_back( os->popString().toChar() ); } } else if(os->getTypeStr() == "function") { t->type=SCRIPT; os->pushValueById(myRule.valueID); Value::Object* theRule = new Value::Object(os); t->onBuild = new Value::Method(os, theRule, "build"); } else { cerr << "[IceTea]: Rule '"<< rule << "' must have it's build property defined as function or array! " << "'" << os->getTypeStr() << "' was given instead." << endl; } t->target = (Value::Object*)(*targets)[target]; input = myExpected; queue->add(t); } }
int main(int argc, char **argv) { #ifdef _MEMMGR HeapManager heap; #endif clock_t from, to; double diff; LongHash lhash; LongMap lmap; StringHash shash; StringMap smap; srand(clock()); int nelems = 10; int naccess = 100; if (argc >= 2) { sscanf(argv[1], "%d", &nelems); } if (argc >= 3) { sscanf(argv[2], "%d", &naccess); } const char *strpool[] = { "hello", "_", "world", "012", "before", "after", "if", "then", "else", "for", "while", "do", "@", "~", "+", "-", "function", "class" }; size_t nstrings = sizeof(strpool) / sizeof(const char*); // fill elements std::vector<std::string> skeys(nelems); std::vector<long> lkeys(nelems); std::cout << "Buid hash and map with " << nelems << " elements" << std::endl; for (int i=0; i<nelems; ++i) { long k = rand(); lkeys[i] = k; int p = rand() % nstrings; int s = rand() % nstrings; skeys[i] = strpool[p]; skeys[i] += strpool[s]; } from = clock(); for (int i=0; i<nelems; ++i) { lhash.insert(lkeys[i], rand()); } to = clock(); diff = double(to - from) / CLOCKS_PER_SEC; std::cout << "LongHash fill " << nelems << " values: " << diff << " (s)" << std::endl; from = clock(); for (int i=0; i<nelems; ++i) { lmap[lkeys[i]] = rand(); } to = clock(); diff = double(to - from) / CLOCKS_PER_SEC; std::cout << "LongMap fill " << nelems << " values: " << diff << " (s)" << std::endl; from = clock(); for (int i=0; i<nelems; ++i) { shash.insert(skeys[i], rand()); } to = clock(); diff = double(to - from) / CLOCKS_PER_SEC; std::cout << "StringHash fill " << nelems << " values: " << diff << " (s)" << std::endl; from = clock(); for (int i=0; i<nelems; ++i) { smap[skeys[i]] = rand(); } to = clock(); diff = double(to - from) / CLOCKS_PER_SEC; std::cout << "StringMap fill " << nelems << " values: " << diff << " (s)" << std::endl; // check datas /* std::cout << "Check data" << std::endl; for (int k=0; k<nelems; ++k) { long v0 = lhash.getValue(lkeys[k]); long v1 = lmap[lkeys[k]]; if (v0 != v1) { std::cout << "Data mismatch at long key \"" << lkeys[k] << "\"" << std::endl; } v0 = shash.getValue(skeys[k]); v1 = smap[skeys[k]]; if (v0 != v1) { std::cout << "Data mismatch at std::string key \"" << skeys[k] << "\"" << std::endl; } } */ // test long map from = clock(); for (int i=0; i<naccess; ++i) { long k = rand() % nelems; long v = lhash.getValue(lkeys[k]); } to = clock(); diff = double(to - from) / CLOCKS_PER_SEC; std::cout << "LongHash " << naccess << " random access: " << diff << " (s)" << std::endl; from = clock(); for (int i=0; i<naccess; ++i) { long k = rand() % nelems; long v = lmap[lkeys[k]]; } to = clock(); diff = double(to - from) / CLOCKS_PER_SEC; std::cout << "LongMap " << naccess << " random access: " << diff << " (s)" << std::endl; // test string map from = clock(); for (int i=0; i<naccess; ++i) { long k = rand() % nelems; long v = shash.getValue(skeys[k]); } to = clock(); diff = double(to - from) / CLOCKS_PER_SEC; std::cout << "StringHash " << naccess << " random access: " << diff << " (s)" << std::endl; from = clock(); for (int i=0; i<naccess; ++i) { long k = rand() % nelems; long v = smap[skeys[k]]; } to = clock(); diff = double(to - from) / CLOCKS_PER_SEC; std::cout << "StringMap " << naccess << " random access: " << diff << " (s)" << std::endl; // test random keys // should make it so we have around 50% chances to find the element // build a new key array size_t numhits = 0; double hitperc = 0.0; std::vector<long> rkeys(2*nelems); for (size_t i=0; i<lkeys.size(); ++i) { rkeys[i] = lkeys[i]; } for (size_t i=nelems; i<size_t(2 * nelems); ++i) { rkeys[i] = rand(); } from = clock(); for (int i=0; i<naccess; ++i) { long k = rkeys[rand() % (2 * nelems)]; long v; if (lhash.getValue(k, v)) { //if (lhash.hasKey(k)) { ++numhits; //long v = lhash.getValue(k); } } to = clock(); diff = double(to - from) / CLOCKS_PER_SEC; hitperc = double(numhits) / double(naccess); std::cout << "LongHash " << naccess << " random keys: " << diff << " (s) [" << (hitperc*100) << " % hit]" << std::endl; /* HashMap<long, long>::iterator hit; numhits = 0; from = clock(); for (int i=0; i<naccess; ++i) { long k = rkeys[rand() % (2 * nelems)]; hit = lhash.find(k); if (hit != lhash.end()) { ++numhits; long v = hit->second; } } to = clock(); diff = double(to - from) / CLOCKS_PER_SEC; hitperc = double(numhits) / double(naccess); std::cout << "LongHash " << naccess << " random keys: " << diff << " (s) [" << (hitperc*100) << " % hit, using iterators]" << std::endl; */ std::map<long,long>::iterator mit; numhits = 0; from = clock(); for (int i=0; i<naccess; ++i) { long k = rkeys[rand() % (2 * nelems)]; mit = lmap.find(k); if (mit != lmap.end()) { ++numhits; long v = mit->second; } } to = clock(); diff = double(to - from) / CLOCKS_PER_SEC; hitperc = double(numhits) / double(naccess); std::cout << "LongMap " << naccess << " random keys: " << diff << " (s) [" << (hitperc*100) << " % hit]" << std::endl; return 0; }