Commit 28db1b19 authored by Georgios Bitzes's avatar Georgios Bitzes
Browse files

Implement iterator to go through expiration events

Ordered by deadline.
parent ef3283da
Pipeline #423928 failed with stages
in 14 minutes and 40 seconds
Subproject commit 18af58123af20bef3578b0f314e6cd4a638c5eb4
Subproject commit 0ef4113c8902d5b79893989a0eaef3354ac79e69
......@@ -63,6 +63,7 @@ add_library(XrdQuarkDB SHARED
redis/Transaction.cc redis/Transaction.hh
storage/ConsistencyScanner.cc storage/ConsistencyScanner.hh
storage/ExpirationEventIterator.cc storage/ExpirationEventIterator.hh
storage/KeyConstants.cc storage/KeyConstants.hh
storage/KeyDescriptor.hh
storage/KeyDescriptorBuilder.cc storage/KeyDescriptorBuilder.hh
......
// ----------------------------------------------------------------------
// File: ExpirationEventIterator.cc
// Author: Georgios Bitzes - CERN
// ----------------------------------------------------------------------
/************************************************************************
* quarkdb - a redis-like highly available key-value store *
* Copyright (C) 2018 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
************************************************************************/
#include "ExpirationEventIterator.hh"
#include "StagingArea.hh"
#include "KeyLocators.hh"
#include "../utils/IntToBinaryString.hh"
using namespace quarkdb;
ExpirationEventIterator::ExpirationEventIterator(StagingArea &st)
: stagingArea(st), iter(stagingArea.getIterator()) {
std::string searchPrefix(1, char(InternalKeyType::kExpirationEvent));
iter->Seek(searchPrefix);
assertDeadlineSanity();
}
ExpirationEventIterator::~ExpirationEventIterator() {
}
bool ExpirationEventIterator::valid() {
if(!iter) return false;
if(!iter->Valid()) {
iter.reset();
return false;
}
if(iter->key()[0] != char(InternalKeyType::kExpirationEvent)) {
iter.reset();
return false;
}
return true;
}
void ExpirationEventIterator::next() {
iter->Next();
assertDeadlineSanity();
}
void ExpirationEventIterator::assertDeadlineSanity() {
if(valid()) {
ClockValue deadline = getDeadline();
qdb_assert(lastDeadline <= deadline);
lastDeadline = deadline;
}
}
ClockValue ExpirationEventIterator::getDeadline() {
return binaryStringToUnsignedInt(iter->key().data()+1);
}
std::string_view ExpirationEventIterator::getRedisKey() {
constexpr size_t offset = 1 + sizeof(ClockValue);
return std::string_view(iter->key().data()+offset, iter->key().size()-offset);
}
// ----------------------------------------------------------------------
// File: ExpirationEventIterator.hh
// Author: Georgios Bitzes - CERN
// ----------------------------------------------------------------------
/************************************************************************
* quarkdb - a redis-like highly available key-value store *
* Copyright (C) 2018 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
************************************************************************/
#ifndef QUARKDB_EXPIRATION_EVENT_ITERATOR_H
#define QUARKDB_EXPIRATION_EVENT_ITERATOR_H
#include <vector>
#include <string_view>
#include "../StateMachine.hh"
namespace quarkdb {
class StagingArea;
using ClockValue = uint64_t;
class ExpirationEventIterator {
public:
ExpirationEventIterator(StagingArea &stagingArea);
virtual ~ExpirationEventIterator();
bool valid();
void next();
ClockValue getDeadline();
std::string_view getRedisKey();
private:
void assertDeadlineSanity();
StagingArea &stagingArea;
ClockValue lastDeadline = 0;
StateMachine::IteratorPtr iter;
};
}
#endif
......@@ -25,6 +25,7 @@
#include "storage/StagingArea.hh"
#include "storage/ReverseLocator.hh"
#include "storage/PatternMatching.hh"
#include "storage/ExpirationEventIterator.hh"
#include "StateMachine.hh"
#include "test-utils.hh"
#include <gtest/gtest.h>
......@@ -699,6 +700,13 @@ TEST_F(State_Machine, Leases) {
stateMachine()->getClock(clk);
ASSERT_EQ(clk, 0u);
{
StagingArea stagingArea(*stateMachine());
ExpirationEventIterator iterator(stagingArea);
ASSERT_FALSE(iterator.valid());
}
bool acquired;
ASSERT_OK(stateMachine()->lease_acquire("my-lease", "some-string", ClockValue(1), 10, acquired));
ASSERT_TRUE(acquired);
......@@ -706,17 +714,55 @@ TEST_F(State_Machine, Leases) {
stateMachine()->getClock(clk);
ASSERT_EQ(clk, 1u);
{
StagingArea stagingArea(*stateMachine());
ExpirationEventIterator iterator(stagingArea);
ASSERT_TRUE(iterator.valid());
ASSERT_EQ(iterator.getDeadline(), 11u);
ASSERT_EQ(iterator.getRedisKey(), "my-lease");
iterator.next();
ASSERT_FALSE(iterator.valid());
}
ASSERT_OK(stateMachine()->lease_acquire("my-lease", "some-string", ClockValue(9), 10, acquired));
ASSERT_TRUE(acquired);
stateMachine()->getClock(clk);
ASSERT_EQ(clk, 9u);
{
StagingArea stagingArea(*stateMachine());
ExpirationEventIterator iterator(stagingArea);
ASSERT_TRUE(iterator.valid());
ASSERT_EQ(iterator.getDeadline(), 19u);
ASSERT_EQ(iterator.getRedisKey(), "my-lease");
iterator.next();
ASSERT_FALSE(iterator.valid());
}
stateMachine()->lease_acquire("my-lease", "some-other-string", ClockValue(12), 10, acquired);
ASSERT_FALSE(acquired);
stateMachine()->getClock(clk);
ASSERT_EQ(clk, 12u);
stateMachine()->lease_acquire("my-lease-2", "some-other-string", ClockValue(13), 10, acquired);
ASSERT_TRUE(acquired);
{
StagingArea stagingArea(*stateMachine());
ExpirationEventIterator iterator(stagingArea);
ASSERT_TRUE(iterator.valid());
ASSERT_EQ(iterator.getDeadline(), 19u);
ASSERT_EQ(iterator.getRedisKey(), "my-lease");
iterator.next();
ASSERT_TRUE(iterator.valid());
ASSERT_EQ(iterator.getDeadline(), 23u);
ASSERT_EQ(iterator.getRedisKey(), "my-lease-2");
iterator.next();
ASSERT_FALSE(iterator.valid());
}
}
static std::string sliceToString(const rocksdb::Slice &slice) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment