Exemple #1
0
/*=========================================
 * 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;
}
Exemple #2
0
/*=========================================
 * 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);
    }
}
Exemple #4
0
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;
}