Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified btree_test
Binary file not shown.
Binary file added cache_performance_demo
Binary file not shown.
Binary file modified content_addressable_demo
Binary file not shown.
Binary file modified content_hash_demo
Binary file not shown.
Binary file modified deduplication_demo
Binary file not shown.
6 changes: 6 additions & 0 deletions include/btree.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "fraction.h"
#include "page_manager.h"
#include "content_storage.h"
#include "page_cache.h"
#include "writer_queue.h"

/*
* BTree that stores the BTreeNodes, ensures it is balanced
Expand All @@ -19,6 +21,8 @@ class BTree {
std::shared_ptr<Page<KeyType>> root;
int maxKeysPerNode; // Maximum keys in each node
ContentStorage<KeyType> content_storage;
PageCache<KeyType> page_cache;
WriterQueue<KeyType> writer_queue;

void insertNonFull(std::shared_ptr<Page<KeyType>> root, const KeyType& key, const ValueType& value);
void splitChild(std::shared_ptr<Page<KeyType>> parent, int index, std::shared_ptr<Page<KeyType>> child);
Expand All @@ -30,10 +34,12 @@ class BTree {

public:
BTree(int maxKeys);
~BTree();
void insert(const KeyType& key, const ValueType& value);
void deleteKey(const KeyType& key);
ValueType* search(const KeyType& key); // Public search method
void printStorageStats() const;
void flush(); // To flush all pending writes

Page<KeyType> findKey(std::shared_ptr<Page<KeyType>> node, const KeyType& key);

Expand Down
56 changes: 56 additions & 0 deletions include/page_cache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#pragma once
#include <unordered_map>
#include <list>
#include <memory>
#include <mutex>
#include <chrono>
#include "page_manager.h"
#include "content_storage.h"

// with metadata
template <typename KeyType>
struct CachedPage {
std::shared_ptr<Page<KeyType>> page;
bool is_dirty;
std::chrono::steady_clock::time_point last_accessed;

CachedPage(std::shared_ptr<Page<KeyType>> p, bool dirty = false)
: page(p), is_dirty(dirty), last_accessed(std::chrono::steady_clock::now()) {}
};

template <typename KeyType>
class PageCache {
private:
// Core cache storage
std::unordered_map<uint16_t, CachedPage<KeyType>> cache;

// LRU tracking
std::list<uint16_t> lru_order;
std::unordered_map<uint16_t, typename std::list<uint16_t>::iterator> lru_iterators;

// For thread safety
mutable std::mutex cache_mutex;

size_t max_cache_size;

// Reference to content storage
ContentStorage<KeyType>* content_storage;

void updateLRU(uint16_t page_id);
void evictLRU();
void evictIfNeeded();

public:
PageCache(ContentStorage<KeyType>* storage, size_t max_size = 100);
~PageCache();

// These are the main cache operations
std::shared_ptr<Page<KeyType>> getPage(uint16_t page_id);
void putPage(uint16_t page_id, std::shared_ptr<Page<KeyType>> page);
void markDirty(uint16_t page_id);

// Cache management
std::vector<std::pair<uint16_t, std::shared_ptr<Page<KeyType>>>> getDirtyPages();
void clearDirtyFlag(uint16_t page_id);
void flushAll();
};
62 changes: 62 additions & 0 deletions include/writer_queue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#pragma once
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <vector>
#include <memory>
#include "page_manager.h"
#include "content_storage.h"
#include "page_cache.h"

template <typename KeyType>
struct WriteRequest {
uint16_t page_id;
std::shared_ptr<Page<KeyType>> page;
std::chrono::steady_clock::time_point timestamp;

WriteRequest(uint16_t id, std::shared_ptr<Page<KeyType>> p)
: page_id(id), page(p), timestamp(std::chrono::steady_clock::now()) {}
};

template <typename KeyType>
class WriterQueue {
private:
// Queue
std::queue<WriteRequest<KeyType>> write_queue;
std::mutex queue_mutex;
std::condition_variable queue_cv;
std::condition_variable empty_cv;

// Thread
std::vector<std::thread> writer_threads;
std::atomic<bool> running;
size_t num_writer_threads;

// References to other components
ContentStorage<KeyType>* content_storage;
PageCache<KeyType>* page_cache;

// Configuration
size_t max_queue_size;
std::chrono::milliseconds batch_timeout;

// Worker thread function
void writerWorker(int worker_id);

// Batch processing
std::vector<WriteRequest<KeyType>> getBatch(size_t max_batch_size);
void processBatch(const std::vector<WriteRequest<KeyType>>& batch, int worker_id);

public:
WriterQueue(ContentStorage<KeyType>* storage, PageCache<KeyType>* cache,
size_t num_threads = 2, size_t max_queue = 1000);
~WriterQueue();

// Queue operations
bool enqueueWrite(uint16_t page_id, std::shared_ptr<Page<KeyType>> page);
void start();
void stop();
void waitForEmpty();
};
27 changes: 20 additions & 7 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,34 @@ SRCDIR = src
OBJDIR = obj

# Source files (only B-tree related files)
SOURCES = src/Btree.cpp src/main.cpp src/page_manager.cpp
SOURCES = src/Btree.cpp src/main.cpp src/page_manager.cpp src/page_cache.cpp src/writer_queue.cpp
OBJECTS = $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)

# Demo source files
DEMO_SOURCES = src/Btree.cpp src/content_hash_demo.cpp src/page_manager.cpp
DEMO_SOURCES = src/Btree.cpp src/content_hash_demo.cpp src/page_manager.cpp src/page_cache.cpp src/writer_queue.cpp
DEMO_OBJECTS = $(DEMO_SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)

# Content addressable demo
ADDRESSABLE_SOURCES = src/Btree.cpp src/content_addressable_demo.cpp src/page_manager.cpp
ADDRESSABLE_SOURCES = src/Btree.cpp src/content_addressable_demo.cpp src/page_manager.cpp src/page_cache.cpp src/writer_queue.cpp
ADDRESSABLE_OBJECTS = $(ADDRESSABLE_SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)

# Deduplication demo
DEDUP_SOURCES = src/Btree.cpp src/deduplication_demo.cpp src/page_manager.cpp
DEDUP_SOURCES = src/Btree.cpp src/deduplication_demo.cpp src/page_manager.cpp src/page_cache.cpp src/writer_queue.cpp
DEDUP_OBJECTS = $(DEDUP_SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)

# Cache performance demo
CACHE_PERF_SOURCES = src/Btree.cpp src/cache_performance_demo.cpp src/page_manager.cpp src/page_cache.cpp src/writer_queue.cpp
CACHE_PERF_OBJECTS = $(CACHE_PERF_SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)

# Target executables
TARGET = btree_test
DEMO_TARGET = content_hash_demo
ADDRESSABLE_TARGET = content_addressable_demo
DEDUP_TARGET = deduplication_demo
CACHE_PERF_TARGET = cache_performance_demo

# Default target
all: $(TARGET) $(DEMO_TARGET) $(ADDRESSABLE_TARGET) $(DEDUP_TARGET)
all: $(TARGET) $(DEMO_TARGET) $(ADDRESSABLE_TARGET) $(DEDUP_TARGET) $(CACHE_PERF_TARGET)

# Create object directory if it doesn't exist
$(OBJDIR):
Expand All @@ -52,9 +57,13 @@ $(ADDRESSABLE_TARGET): $(ADDRESSABLE_OBJECTS)
$(DEDUP_TARGET): $(DEDUP_OBJECTS)
$(CXX) $(DEDUP_OBJECTS) -o $(DEDUP_TARGET)

# Link cache performance demo executable
$(CACHE_PERF_TARGET): $(CACHE_PERF_OBJECTS)
$(CXX) $(CACHE_PERF_OBJECTS) -o $(CACHE_PERF_TARGET)

# Clean build files
clean:
rm -rf $(OBJDIR) $(TARGET) $(DEMO_TARGET) $(ADDRESSABLE_TARGET) $(DEDUP_TARGET)
rm -rf $(OBJDIR) $(TARGET) $(DEMO_TARGET) $(ADDRESSABLE_TARGET) $(DEDUP_TARGET) $(CACHE_PERF_TARGET)

# Run the test
run: $(TARGET)
Expand All @@ -72,6 +81,10 @@ addressable: $(ADDRESSABLE_TARGET)
dedup: $(DEDUP_TARGET)
./$(DEDUP_TARGET)

# Run the cache performance demo
cache_perf: $(CACHE_PERF_TARGET)
./$(CACHE_PERF_TARGET)

# Run all tests (for CI/CD compatibility)
tests: $(TARGET) $(DEMO_TARGET) $(ADDRESSABLE_TARGET) $(DEDUP_TARGET)
@echo "=== Running Content Hash Demo ==="
Expand All @@ -87,4 +100,4 @@ tests: $(TARGET) $(DEMO_TARGET) $(ADDRESSABLE_TARGET) $(DEDUP_TARGET)
@echo -e "insert 1 apple\ninsert 2 banana\nsearch 1\nsearch 2\nquit" | ./$(TARGET) > /dev/null
@echo "All tests passed!"

.PHONY: all clean run demo addressable dedup tests
.PHONY: all clean run demo addressable dedup cache_perf tests
Loading