I SAW PUT COMMAND LOG!!
This commit is contained in:
parent
ab7c39ae8e
commit
d23f9b11b7
@ -10,7 +10,7 @@ namespace usub::core
|
|||||||
: capacity_(capacity), head_(0), tail_(0)
|
: capacity_(capacity), head_(0), tail_(0)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < capacity_; ++i)
|
for (size_t i = 0; i < capacity_; ++i)
|
||||||
new (&buffer_[i]) Command();
|
new(&buffer_[i]) Command();
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedCommandQueue::~SharedCommandQueue()
|
SharedCommandQueue::~SharedCommandQueue()
|
||||||
@ -102,4 +102,28 @@ namespace usub::core
|
|||||||
tail_.store((tail + copied) % capacity_, std::memory_order_release);
|
tail_.store((tail + copied) % capacity_, std::memory_order_release);
|
||||||
return copied;
|
return copied;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Command* SharedCommandQueue::peek(size_t index)
|
||||||
|
{
|
||||||
|
size_t tail = tail_.load(std::memory_order_relaxed);
|
||||||
|
size_t head = head_.load(std::memory_order_acquire);
|
||||||
|
|
||||||
|
if (tail == head)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return &buffer_[tail % capacity_];
|
||||||
|
}
|
||||||
|
|
||||||
|
void SharedCommandQueue::pop()
|
||||||
|
{
|
||||||
|
size_t tail = tail_.load(std::memory_order_relaxed);
|
||||||
|
tail_.store((tail + 1) % capacity_, std::memory_order_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SharedCommandQueue::pending_count() const
|
||||||
|
{
|
||||||
|
size_t head = head_.load(std::memory_order_acquire);
|
||||||
|
size_t tail = tail_.load(std::memory_order_relaxed);
|
||||||
|
return (head + capacity_ - tail) % capacity_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,11 +31,68 @@ namespace usub::core
|
|||||||
|
|
||||||
size_t try_pop_batch(Command* out, size_t max_count);
|
size_t try_pop_batch(Command* out, size_t max_count);
|
||||||
|
|
||||||
|
Command* peek(size_t index);
|
||||||
|
|
||||||
|
void pop();
|
||||||
|
|
||||||
|
size_t pending_count() const;
|
||||||
|
|
||||||
|
Command* raw_buffer() noexcept { return buffer_; }
|
||||||
|
size_t capacity() const noexcept { return capacity_; }
|
||||||
|
std::atomic<size_t>& head() noexcept { return head_; }
|
||||||
|
std::atomic<size_t>& tail() noexcept { return tail_; }
|
||||||
|
|
||||||
|
bool enqueue_put(const usub::utils::Hash128& key, const std::string& value)
|
||||||
|
{
|
||||||
|
size_t head = head_.load(std::memory_order_relaxed);
|
||||||
|
size_t next_head = (head + 1) % capacity_;
|
||||||
|
if (next_head == tail_.load(std::memory_order_acquire))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Command& slot = buffer_[head];
|
||||||
|
slot.op = OperationType::PUT;
|
||||||
|
slot.key = key;
|
||||||
|
slot.value_size = static_cast<uint32_t>(value.size());
|
||||||
|
std::memcpy(slot.value, value.data(), value.size());
|
||||||
|
slot.response_size = 0;
|
||||||
|
slot.response_ready.store(0, std::memory_order_relaxed);
|
||||||
|
slot.ready.store(1, std::memory_order_release);
|
||||||
|
|
||||||
|
head_.store(next_head, std::memory_order_release);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool enqueue_find(const usub::utils::Hash128& key)
|
||||||
|
{
|
||||||
|
size_t head = head_.load(std::memory_order_relaxed);
|
||||||
|
size_t next_head = (head + 1) % capacity_;
|
||||||
|
if (next_head == tail_.load(std::memory_order_acquire))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Command& slot = buffer_[head];
|
||||||
|
slot.op = OperationType::FIND;
|
||||||
|
slot.key = key;
|
||||||
|
slot.value_size = 0;
|
||||||
|
slot.response_size = 0;
|
||||||
|
slot.response_ready.store(0, std::memory_order_relaxed);
|
||||||
|
slot.ready.store(1, std::memory_order_release);
|
||||||
|
|
||||||
|
head_.store(next_head, std::memory_order_release);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool await_response(Command& cmd)
|
||||||
|
{
|
||||||
|
while (cmd.response_ready.load(std::memory_order_acquire) == 0)
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
return cmd.response_size != 0;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t capacity_;
|
size_t capacity_;
|
||||||
std::atomic<size_t> head_;
|
|
||||||
std::atomic<size_t> tail_;
|
|
||||||
Command* commands_;
|
Command* commands_;
|
||||||
|
alignas(64) std::atomic<size_t> head_;
|
||||||
|
alignas(64) std::atomic<size_t> tail_;
|
||||||
alignas(64) Command buffer_[];
|
alignas(64) Command buffer_[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,17 @@ namespace usub::core
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SharedMemoryManager::needs_init() const noexcept
|
||||||
|
{
|
||||||
|
const uint8_t* base = reinterpret_cast<const uint8_t*>(this->shm_ptr);
|
||||||
|
for (size_t i = 0; i < sizeof(uint64_t); ++i)
|
||||||
|
{
|
||||||
|
if (base[i] != 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void SharedMemoryManager::create()
|
void SharedMemoryManager::create()
|
||||||
{
|
{
|
||||||
::shm_unlink((this->shm_name).c_str());
|
::shm_unlink((this->shm_name).c_str());
|
||||||
|
@ -32,6 +32,8 @@ namespace usub::core
|
|||||||
|
|
||||||
static bool exists(const std::string& name);
|
static bool exists(const std::string& name);
|
||||||
|
|
||||||
|
[[nodiscard]] bool needs_init() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void create();
|
void create();
|
||||||
|
|
||||||
|
44
core/UDB.cpp
44
core/UDB.cpp
@ -18,16 +18,30 @@ namespace usub::core
|
|||||||
compactor_(this->version_manager_),
|
compactor_(this->version_manager_),
|
||||||
running_(true)
|
running_(true)
|
||||||
{
|
{
|
||||||
if (create_new)
|
if (shm_manager_.needs_init())
|
||||||
new(this->shm_manager_.base_ptr()) SharedCommandQueue(this->shm_queue_capacity_);
|
{
|
||||||
this->command_queue_ = reinterpret_cast<SharedCommandQueue*>(this->shm_manager_.base_ptr());
|
new(shm_manager_.base_ptr()) SharedCommandQueue(shm_queue_capacity_);
|
||||||
|
}
|
||||||
|
|
||||||
|
command_queue_ = reinterpret_cast<SharedCommandQueue*>(shm_manager_.base_ptr());
|
||||||
|
|
||||||
recover_from_logs();
|
recover_from_logs();
|
||||||
|
|
||||||
this->background_flush_thread_ = std::thread(&UDB::background_flush_worker, this);
|
background_flush_thread_ = std::thread(&UDB::background_flush_worker, this);
|
||||||
compactor_.run();
|
compactor_.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// {
|
||||||
|
// if (create_new)
|
||||||
|
// new(this->shm_manager_.base_ptr()) SharedCommandQueue(this->shm_queue_capacity_);
|
||||||
|
// this->command_queue_ = reinterpret_cast<SharedCommandQueue*>(this->shm_manager_.base_ptr());
|
||||||
|
//
|
||||||
|
// recover_from_logs();
|
||||||
|
//
|
||||||
|
// this->background_flush_thread_ = std::thread(&UDB::background_flush_worker, this);
|
||||||
|
// compactor_.run();
|
||||||
|
// }
|
||||||
|
|
||||||
UDB::~UDB()
|
UDB::~UDB()
|
||||||
{
|
{
|
||||||
running_ = false;
|
running_ = false;
|
||||||
@ -61,21 +75,24 @@ namespace usub::core
|
|||||||
{
|
{
|
||||||
std::cout << "[UDB] Server for DB '" << this->db_name_ << "' started.\n";
|
std::cout << "[UDB] Server for DB '" << this->db_name_ << "' started.\n";
|
||||||
|
|
||||||
constexpr size_t BATCH_SIZE = 64;
|
|
||||||
Command batch[BATCH_SIZE];
|
|
||||||
|
|
||||||
while (this->running_)
|
while (this->running_)
|
||||||
{
|
{
|
||||||
size_t count = this->command_queue_->try_pop_batch(batch, BATCH_SIZE);
|
Command* cmd = this->command_queue_->peek(0);
|
||||||
if (count == 0)
|
|
||||||
|
if (!cmd)
|
||||||
{
|
{
|
||||||
std::this_thread::sleep_for(std::chrono::microseconds(500));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < count; ++i)
|
if (cmd->ready.load(std::memory_order_acquire) == 1)
|
||||||
{
|
{
|
||||||
this->process_command(batch[i]);
|
process_command(*cmd);
|
||||||
|
this->command_queue_->pop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,6 +103,7 @@ namespace usub::core
|
|||||||
{
|
{
|
||||||
case OperationType::PUT:
|
case OperationType::PUT:
|
||||||
{
|
{
|
||||||
|
std::cout << "PUT\n";
|
||||||
std::string value(cmd.value, cmd.value_size);
|
std::string value(cmd.value, cmd.value_size);
|
||||||
this->fast_cache_[cmd.key] = value;
|
this->fast_cache_[cmd.key] = value;
|
||||||
this->memtable_manager_.put(cmd.key, value);
|
this->memtable_manager_.put(cmd.key, value);
|
||||||
@ -93,6 +111,7 @@ namespace usub::core
|
|||||||
}
|
}
|
||||||
case OperationType::DELETE:
|
case OperationType::DELETE:
|
||||||
{
|
{
|
||||||
|
std::cout << "DELETE\n";
|
||||||
fast_cache_.erase(cmd.key);
|
fast_cache_.erase(cmd.key);
|
||||||
memtable_manager_.remove(cmd.key);
|
memtable_manager_.remove(cmd.key);
|
||||||
break;
|
break;
|
||||||
@ -102,6 +121,7 @@ namespace usub::core
|
|||||||
auto it = fast_cache_.find(cmd.key);
|
auto it = fast_cache_.find(cmd.key);
|
||||||
if (it != fast_cache_.end())
|
if (it != fast_cache_.end())
|
||||||
{
|
{
|
||||||
|
std::cout << "FIND\n";
|
||||||
std::string value = it->second;
|
std::string value = it->second;
|
||||||
cmd.response_size = static_cast<uint32_t>(value.size());
|
cmd.response_size = static_cast<uint32_t>(value.size());
|
||||||
std::memcpy(cmd.response, value.data(), value.size());
|
std::memcpy(cmd.response, value.data(), value.size());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user