Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
lalinsky committed Mar 4, 2024
1 parent 79f1bf4 commit 92a98b8
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 10 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ project(fpserver)

cmake_policy(SET CMP0071 NEW)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)

Expand Down
6 changes: 2 additions & 4 deletions src/fpindex/base_segment.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#include <cstdint>
#include <vector>

#include "fpindex/search_result.h"
#include "fpindex/proto/internal.pb.h"
#include "fpindex/search_result.h"

namespace fpindex {

Expand All @@ -21,9 +21,7 @@ class BaseSegment {
virtual std::vector<SearchResult> Search(const std::vector<uint32_t> &hashes);

protected:
BaseSegment(uint32_t id) {
info_.set_id(id);
}
BaseSegment(uint32_t id) { info_.set_id(id); }

private:
SegmentInfo info_;
Expand Down
2 changes: 1 addition & 1 deletion src/fpindex/oplog.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Oplog {
bool CreateTable();

private:
std::mutex mutex_;
std::mutex mutex_;
std::shared_ptr<sqlite3> db_;
};

Expand Down
26 changes: 26 additions & 0 deletions src/fpindex/oplog_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include <gtest/gtest.h>

#include "fpindex/oplog.h"
#include "fpindex/io/sqlite.h"

using namespace fpindex;

TEST(OplogTest, Open) {
auto db = io::OpenDatabase(":memory:", true);
Oplog oplog(db);
ASSERT_TRUE(oplog.Open());
}

TEST(OplogTest, Write) {
auto db = io::OpenDatabase(":memory:", true);
Oplog oplog(db);
ASSERT_TRUE(oplog.Open());

OplogEntries entries;
auto entry = entries.add_entries();
entry->set_op_id(1);
entry->mutable_set_attribute()->set_key("key");
entry->mutable_set_attribute()->set_value("value");

ASSERT_TRUE(oplog.Write(entries));
}
29 changes: 28 additions & 1 deletion src/fpindex/segment_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,49 @@
#include <mutex>

#include "fpindex/search_result.h"
#include "fpindex/logging.h"
#include "fpindex/segment.h"
#include "fpindex/segment_file_format.h"

namespace fpindex {

bool SegmentBuilder::Add(uint32_t id, const std::vector<uint32_t>& hashes) {
bool SegmentBuilder::InsertOrUpdate(uint32_t id, const std::vector<uint32_t>& hashes) {
std::unique_lock<std::shared_mutex> lock(mutex_);
if (frozen_) {
return false;
}
DeleteInternal(id);
for (auto hash : hashes) {
data_.insert(std::make_pair(hash, id));
}
ids_.insert(id);
return true;
}

bool SegmentBuilder::Delete(uint32_t id) {
std::unique_lock<std::shared_mutex> lock(mutex_);
if (frozen_) {
return false;
}
DeleteInternal(id);
return true;
}

void SegmentBuilder::DeleteInternal(uint32_t id) {
if (auto it = ids_.find(id); it != ids_.end()) {
ids_.erase(it);
std::erase_if(data_, [id](const auto& pair) { return pair.second == id; });
}
}

bool SegmentBuilder::Contains(uint32_t id) {
std::shared_lock<std::shared_mutex> lock;
if (!frozen_) {
lock = std::shared_lock<std::shared_mutex>(mutex_);
}
return ids_.contains(id);
}

bool SegmentBuilder::IsFrozen() {
std::unique_lock<std::shared_mutex> lock(mutex_);
return frozen_;
Expand Down
9 changes: 8 additions & 1 deletion src/fpindex/segment_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <atomic>
#include <map>
#include <shared_mutex>
#include <unordered_set>
#include <vector>

#include "fpindex/base_segment.h"
Expand All @@ -18,7 +19,10 @@ class SegmentBuilder : public BaseSegment {
SegmentBuilder(const SegmentBuilder&) = delete;
SegmentBuilder& operator=(const SegmentBuilder&) = delete;

bool Add(uint32_t id, const std::vector<uint32_t>& values);
bool InsertOrUpdate(uint32_t id, const std::vector<uint32_t>& values);
bool Delete(uint32_t id);

bool Contains(uint32_t id);

bool Search(const std::vector<uint32_t>& hashes, std::vector<SearchResult>* results) override;

Expand All @@ -30,8 +34,11 @@ class SegmentBuilder : public BaseSegment {
std::shared_ptr<Segment> Save(const std::shared_ptr<io::File>& file);

private:
void DeleteInternal(uint32_t id);

std::shared_mutex mutex_;
std::multimap<uint32_t, uint32_t> data_;
std::unordered_set<uint32_t> ids_;
std::atomic<bool> frozen_{false};
};

Expand Down
45 changes: 43 additions & 2 deletions src/fpindex/segment_builder_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,50 @@ TEST(SegmentBuilderTest, SearchEmpty) {
ASSERT_TRUE(results.empty());
}

TEST(SegmentBuilderTest, Insert) {
SegmentBuilder segment(0);
segment.InsertOrUpdate(1, {1, 2, 3});

std::vector<SearchResult> results;

ASSERT_TRUE(segment.Search({1,2,3}, &results));
ASSERT_EQ(1, results.size());

ASSERT_TRUE(segment.Search({4, 5,6}, &results));
ASSERT_EQ(0, results.size());
}

TEST(SegmentBuilderTest, Update) {
SegmentBuilder segment(0);
segment.InsertOrUpdate(1, {1, 2, 3});
segment.InsertOrUpdate(1, {4, 5, 6});

std::vector<SearchResult> results;

EXPECT_TRUE(segment.Search({1,2,3}, &results));
EXPECT_EQ(0, results.size());

EXPECT_TRUE(segment.Search({4, 5,6}, &results));
EXPECT_EQ(1, results.size());
}

TEST(SegmentBuilderTest, Delete) {
SegmentBuilder segment(0);
segment.InsertOrUpdate(1, {1, 2, 3});
segment.Delete(1);

std::vector<SearchResult> results;

ASSERT_TRUE(segment.Search({1,2,3}, &results));
ASSERT_EQ(0, results.size());

ASSERT_TRUE(segment.Search({4, 5,6}, &results));
ASSERT_EQ(0, results.size());
}

TEST(SegmentBuilderTest, SearchExactMatch) {
SegmentBuilder segment(0);
segment.Add(1, {1, 2, 3});
segment.InsertOrUpdate(1, {1, 2, 3});

std::vector<uint32_t> query{1, 2, 3};
std::vector<SearchResult> results;
Expand All @@ -31,7 +72,7 @@ TEST(SegmentBuilderTest, SearchExactMatch) {

TEST(SegmentBuilderTest, Save) {
SegmentBuilder segment(0);
segment.Add(1, {1, 2, 3});
segment.InsertOrUpdate(1, {1, 2, 3});

auto file = std::make_shared<io::MemoryFile>();
auto segment2 = segment.Save(file);
Expand Down

0 comments on commit 92a98b8

Please sign in to comment.