QueryData EventSubscriberPlugin::get(EventTime start, EventTime stop) { QueryData results; // Get the records for this time range. auto indexes = getIndexes(start, stop); auto records = getRecords(indexes); std::string events_key = "data." + dbNamespace(); std::vector<std::string> mapped_records; for (const auto& record : records) { if (record.second >= start && (record.second <= stop || stop == 0)) { mapped_records.push_back(events_key + "." + record.first); } } if (FLAGS_events_optimize && !records.empty()) { // If records were returned save the ordered-last as the optimization EID. unsigned long int eidr = 0; if (safeStrtoul(records.back().first, 10, eidr)) { optimize_eid_ = static_cast<size_t>(eidr); auto index_key = "optimize_id." + dbNamespace(); setDatabaseValue(kEvents, index_key, records.back().first); } } // Select mapped_records using event_ids as keys. std::string data_value; for (const auto& record : mapped_records) { Row r; auto status = getDatabaseValue(kEvents, record, data_value); if (data_value.length() == 0) { // There is no record here, interesting error case. continue; } status = deserializeRowJSON(data_value, r); data_value.clear(); if (status.ok()) { results.push_back(std::move(r)); } } if (getEventsExpiry() > 0) { // Set the expire time to NOW - "configured lifetime". // Index retrieval will apply the constraints checking and auto-expire. expire_time_ = getUnixTime() - getEventsExpiry(); } return results; }
TEST_F(EventsDatabaseTests, test_gentable) { auto sub = std::make_shared<DBFakeEventSubscriber>(); auto status = sub->testAdd(1); status = sub->testAdd(2); status = sub->testAdd(11); status = sub->testAdd(61); status = sub->testAdd((1 * 3600) + 1); status = sub->testAdd((2 * 3600) + 1); ASSERT_EQ(0U, sub->optimize_time_); ASSERT_EQ(0U, sub->expire_time_); ASSERT_EQ(0U, sub->min_expiration_); auto t = getUnixTime(); sub->testAdd(t - 1); sub->testAdd(t); sub->testAdd(t + 1); // Test the expire workflow by creating a short expiration time. sub->setEventsExpiry(10); std::vector<std::string> keys; scanDatabaseKeys("events", keys); // 9 data records, 1 eid counter, 3 indexes, 15 index records. // Depending on the moment, an additional 3 indexes may be introduced. EXPECT_LE(16U, keys.size()); // Perform a "select" equivalent. auto results = genRows(sub.get()); // Expect all non-expired results: 11, + EXPECT_EQ(9U, results.size()); // The expiration time is now - events_expiry +/ 60. EXPECT_LT(t - (sub->getEventsExpiry() * 2), sub->expire_time_ + 60); EXPECT_GT(t, sub->expire_time_); // The optimize time will not be changed. ASSERT_EQ(0U, sub->optimize_time_); results = genRows(sub.get()); EXPECT_EQ(3U, results.size()); results = genRows(sub.get()); EXPECT_EQ(3U, results.size()); keys.clear(); scanDatabaseKeys("events", keys); EXPECT_LE(6U, keys.size()); }