示例#1
0
TEST(FunctionScheduler, AddAfterStart) {
  int total = 0;
  FunctionScheduler fs;
  fs.addFunction([&] { total += 2; }, testInterval(2), "add2");
  fs.addFunction([&] { total += 3; }, testInterval(2), "add3");
  fs.start();
  delay(3);
  EXPECT_EQ(10, total);
  fs.addFunction([&] { total += 2; }, testInterval(3), "add22");
  delay(2);
  EXPECT_EQ(17, total);
}
示例#2
0
ExecStreamResult BTreeSearchExecStream::innerFetchLoop(
    ExecStreamQuantum const &quantum,
    uint &nTuples)
{
    for (;;) {
        if (nTuples >= quantum.nTuplesMax) {
            return EXECRC_QUANTUM_EXPIRED;
        }
        if (reachedTupleLimit(nTuples)) {
            return EXECRC_BUF_OVERFLOW;
        }
        if (pOutAccessor->produceTuple(tupleData)) {
            ++nTuples;
        } else {
            return EXECRC_BUF_OVERFLOW;
        }
        if (pReader->searchNext()) {
            if (testInterval()) {
                projAccessor.unmarshal(
                    tupleData.begin() + nJoinAttributes);
                // continue with inner fetch loop
                continue;
            }
        }
        pReader->endSearch();
        // break out of this loop to enable a new key search
        return EXECRC_YIELD;
    }
}
示例#3
0
TEST(FunctionScheduler, AddInvalid) {
  int total = 0;
  FunctionScheduler fs;
  // interval may not be negative
  EXPECT_THROW(fs.addFunction([&] { total += 2; }, testInterval(-1), "add2"),
               std::exception);
  EXPECT_FALSE(fs.cancelFunction("addNoFunc"));
}
示例#4
0
TEST(FunctionScheduler, SimpleAdd) {
  int total = 0;
  FunctionScheduler fs;
  fs.addFunction([&] { total += 2; }, testInterval(2), "add2");
  fs.start();
  delay(1);
  EXPECT_EQ(2, total);
  fs.shutdown();
  delay(2);
  EXPECT_EQ(2, total);
}
示例#5
0
TEST(FunctionScheduler, AddCancel) {
  int total = 0;
  FunctionScheduler fs;
  fs.addFunction([&] { total += 2; }, testInterval(2), "add2");
  fs.start();
  delay(1);
  EXPECT_EQ(2, total);
  delay(2);
  EXPECT_EQ(4, total);
  EXPECT_TRUE(fs.cancelFunction("add2"));
  EXPECT_FALSE(fs.cancelFunction("NO SUCH FUNC"));
  delay(2);
  EXPECT_EQ(4, total);
  fs.addFunction([&] { total += 1; }, testInterval(2), "add2");
  EXPECT_FALSE(fs.start()); // already running
  delay(1);
  EXPECT_EQ(5, total);
  delay(2);
  EXPECT_EQ(6, total);
  fs.shutdown();
}
示例#6
0
TEST(FunctionScheduler, StartDelay) {
  int total = 0;
  FunctionScheduler fs;
  fs.addFunction([&] { total += 2; }, testInterval(2), "add2",
                 testInterval(2));
  fs.addFunction([&] { total += 3; }, testInterval(3), "add3",
                 testInterval(2));
  EXPECT_THROW(fs.addFunction([&] { total += 2; }, testInterval(3),
                              "addX", testInterval(-1)), std::exception);
  fs.start();
  delay(1); // t1
  EXPECT_EQ(0, total);
  // t2 : add2 total=2
  // t2 : add3 total=5
  delay(2); // t3
  EXPECT_EQ(5, total);
  // t4 : add2: total=7
  // t5 : add3: total=10
  // t6 : add2: total=12
  delay(4); // t7
  EXPECT_EQ(12, total);
  fs.cancelFunction("add2");
  // t8 : add3: total=15
  delay(2); // t9
  EXPECT_EQ(15, total);
  fs.shutdown();
  delay(3);
  EXPECT_EQ(15, total);
  fs.shutdown();
}
示例#7
0
TEST(FunctionScheduler, AddWhileRunning) {
  int total = 0;
  FunctionScheduler fs;
  fs.start();
  delay(1);
  fs.addFunction([&] { total += 2; }, testInterval(2), "add2");
  // The function should be invoked nearly immediately when we add it
  // and the FunctionScheduler is already running
  usleep(50000);
  EXPECT_EQ(2, total);
  delay(2);
  EXPECT_EQ(4, total);
}
示例#8
0
TEST(FunctionScheduler, AddMultiple) {
  int total = 0;
  FunctionScheduler fs;
  fs.addFunction([&] { total += 2; }, testInterval(2), "add2");
  fs.addFunction([&] { total += 3; }, testInterval(3), "add3");
// function name already exists
  EXPECT_THROW(fs.addFunction([&] { total += 2; }, testInterval(2),
                              "add2"), std::exception);

  fs.start();
  delay(1);
  EXPECT_EQ(5, total);
  delay(4);
  EXPECT_EQ(12, total);
  EXPECT_TRUE(fs.cancelFunction("add2"));
  delay(2);
  EXPECT_EQ(15, total);
  fs.shutdown();
  delay(3);
  EXPECT_EQ(15, total);
  fs.shutdown();
}
示例#9
0
TEST(FunctionScheduler, ShutdownStart) {
  int total = 0;
  FunctionScheduler fs;
  fs.addFunction([&] { total += 2; }, testInterval(2), "add2");
  fs.start();
  delay(1);
  fs.shutdown();
  fs.start();
  delay(1);
  EXPECT_EQ(4, total);
  EXPECT_FALSE(fs.cancelFunction("add3")); // non existing
  delay(2);
  EXPECT_EQ(6, total);
}
示例#10
0
TEST(FunctionScheduler, NoShutdown) {
  int total = 0;
  {
    FunctionScheduler fs;
    fs.addFunction([&] { total += 2; }, testInterval(1), "add2");
    fs.start();
    usleep(50000);
    EXPECT_EQ(2, total);
  }
  // Destroyed the FunctionScheduler without calling shutdown.
  // Everything should have been cleaned up, and the function will no longer
  // get called.
  delay(2);
  EXPECT_EQ(2, total);
}
示例#11
0
TEST(FunctionScheduler, AddCancel2) {
  int total = 0;
  FunctionScheduler fs;

  // Test adds and cancels while the scheduler is stopped
  EXPECT_FALSE(fs.cancelFunction("add2"));
  fs.addFunction([&] { total += 1; }, testInterval(2), "add2");
  EXPECT_TRUE(fs.cancelFunction("add2"));
  EXPECT_FALSE(fs.cancelFunction("add2"));
  fs.addFunction([&] { total += 2; }, testInterval(2), "add2");
  fs.addFunction([&] { total += 3; }, testInterval(3), "add3");

  EXPECT_EQ(0, total);
  fs.start();
  delay(1);
  EXPECT_EQ(5, total);

  // Cancel add2 while the scheduler is running
  EXPECT_TRUE(fs.cancelFunction("add2"));
  EXPECT_FALSE(fs.cancelFunction("add2"));
  EXPECT_FALSE(fs.cancelFunction("bogus"));

  delay(3);
  EXPECT_EQ(8, total);
  EXPECT_TRUE(fs.cancelFunction("add3"));

  // Test a function that cancels itself
  int selfCancelCount = 0;
  fs.addFunction(
      [&] {
        ++selfCancelCount;
        if (selfCancelCount > 2) {
          fs.cancelFunction("selfCancel");
        }
      },
      testInterval(1), "selfCancel", testInterval(1));
  delay(4);
  EXPECT_EQ(3, selfCancelCount);
  EXPECT_FALSE(fs.cancelFunction("selfCancel"));

  // Test a function that schedules another function
  int adderCount = 0;
  int fn2Count = 0;
  auto fn2 = [&] { ++fn2Count; };
  auto fnAdder = [&] {
    ++adderCount;
    if (adderCount == 2) {
      fs.addFunction(fn2, testInterval(3), "fn2", testInterval(2));
    }
  };
  fs.addFunction(fnAdder, testInterval(4), "adder");
  // t0: adder fires
  delay(1); // t1
  EXPECT_EQ(1, adderCount);
  EXPECT_EQ(0, fn2Count);
  // t4: adder fires, schedules fn2
  delay(4); // t5
  EXPECT_EQ(2, adderCount);
  EXPECT_EQ(0, fn2Count);
  // t6: fn2 fires
  delay(2); // t7
  EXPECT_EQ(2, adderCount);
  EXPECT_EQ(1, fn2Count);
  // t8: adder fires
  // t9: fn2 fires
  delay(3); // t10
  EXPECT_EQ(3, adderCount);
  EXPECT_EQ(2, fn2Count);
  EXPECT_TRUE(fs.cancelFunction("fn2"));
  EXPECT_TRUE(fs.cancelFunction("adder"));
  delay(5); // t10
  EXPECT_EQ(3, adderCount);
  EXPECT_EQ(2, fn2Count);

  EXPECT_EQ(8, total);
  EXPECT_EQ(3, selfCancelCount);
}
示例#12
0
bool BTreeSearchExecStream::searchForKey()
{
    switch (lowerBoundDirective) {
    case SEARCH_UNBOUNDED_LOWER:
        if (pSearchKey->size() <= 1) {
            pReader->searchFirst();
            break;
        }
        // otherwise, this is the case where we have > 1 key and a
        // non-equality search on the last key; in this case, we need
        // to position to the equality portion of the key
    case SEARCH_CLOSED_LOWER:
        pReader->searchForKey(*pSearchKey, DUP_SEEK_BEGIN, leastUpper);
        break;
    case SEARCH_OPEN_LOWER:
        pReader->searchForKey(*pSearchKey, DUP_SEEK_END, leastUpper);
        break;
    default:
        permFail(
            "unexpected lower bound directive:  "
            << (char) lowerBoundDirective);
    }

    bool match = true;
    if (preFilterNulls && pSearchKey->containsNull(searchKeyProj)) {
        // null never matches when preFilterNulls is true;
        // TODO:  so don't bother searching, but need a way
        // to fake pReader->isPositioned()
        match = false;
    } else {
        if (pReader->isSingular()) {
            // Searched past end of tree.
            match = false;
        } else {
            if (preFilterNulls
                && upperBoundData.containsNull(upperBoundKeyProj))
            {
                match = false;
            } else {
                match = testInterval();
            }
        }
    }

    if (!match) {
        if (!outerJoin) {
            pReader->endSearch();
            return false;
        }
        // no match, so make up null values for the missing attributes
        for (uint i = nJoinAttributes; i < tupleData.size(); ++i) {
            tupleData[i].pData = NULL;
        }
    } else {
        projAccessor.unmarshal(
            tupleData.begin() + nJoinAttributes);
    }

    // propagate join attributes
    if (inputJoinAccessor.size()) {
        inputJoinAccessor.unmarshal(tupleData);
    }

    return true;
}