first version of fast lruk

This commit is contained in:
2024-04-25 10:10:49 +00:00
parent 0c0d4684bb
commit 36a615aaad
10 changed files with 498 additions and 3 deletions

9
bpt/include/bpt/config.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef CONFIG_H
#define CONFIG_H
#include <cstddef>
extern const size_t kPageSize;
typedef unsigned int default_numeric_index_t;
typedef default_numeric_index_t page_id_t;
typedef default_numeric_index_t block_id_t;
typedef default_numeric_index_t frame_id_t;
#endif

View File

@ -0,0 +1,46 @@
#ifndef DISK_MANAGER_H
#define DISK_MANAGER_H
#include <cstdio>
#include <string>
#include "config.h"
extern const size_t kPageSize;
class DiskManager {
/**
* The Data Structure on Disk:
* [Internal Page] [Page 1] [Page 2] .....
* In Internal Page, the first meta_data_size bytes are used to store
* metadata(first_empty_page_id, current_total_page_count, current_none_empty_page_count), the rest are allocated to
* raw_data_memory.
* When a page is Deallocated, the first sizeof(page_id_t) bytes are used to store the next empty page
* id, then update first_empty_page_id, just like a list. To avoid unnecessary cache, use C style file operation
* instead of fstream. Note that the page_id is the offset of the page in the file, as the first page is internal,
* thus page_id is 1-based. In the list of empty pages, if the there is no next empty page, the value is 0(the same
* for first_empty_page_id).
*/
public:
explicit DiskManager(const std::string &file_path_);
~DiskManager();
char *RawDataMemory();
size_t RawDatMemorySize();
void FlushInternalPage();
void Close();
void ReadPage(page_id_t page_id, char *page_data_ptr);
void WritePage(page_id_t page_id, const char *page_data_ptr); // in fact, the page_id is the offest
bool CurrentFileIsNew();
page_id_t AllocNewEmptyPageId();
void DeallocatePage(page_id_t page_id);
size_t CurrentTotalPageCount();
size_t CurrentNoneEmptyPageCount();
private:
std::string file_path;
page_id_t first_empty_page_id;
size_t current_total_page_count;
size_t current_none_empty_page_count;
static const size_t meta_data_size = sizeof(page_id_t) + sizeof(size_t) + sizeof(size_t);
char *raw_data_memory;
FILE *fp;
bool is_new;
char *page_buf;
};
#endif

View File

@ -0,0 +1,72 @@
#ifndef REPLACER_H
#define REPLACER_H
#include <cstddef>
#include <mutex>
#include "bpt/config.h"
class LRUKReplacer {
public:
LRUKReplacer() = delete;
explicit LRUKReplacer(size_t max_frame_count, size_t k_value);
~LRUKReplacer();
bool TryEvictLeastImportant(frame_id_t &frame_id);
void RecordAccess(frame_id_t frame_id);
void SetEvictable(frame_id_t frame_id, bool evitable);
bool TryEvictExactFrame(frame_id_t frame_id);
LRUKReplacer &operator=(const LRUKReplacer &) = delete;
size_t GetCurrentEvitableCount();
private:
struct LRUChainNodeType { // for not has k visit
frame_id_t frame_id;
LRUChainNodeType *prev, *next;
LRUChainNodeType() = delete;
explicit LRUChainNodeType(frame_id_t frame_id, LRUChainNodeType *prev, LRUChainNodeType *next)
: frame_id(frame_id), prev(prev), next(next) {}
};
struct MainChainNodeType { // for has k visit
frame_id_t frame_id;
size_t time_stamp;
MainChainNodeType *prev, *next;
MainChainNodeType *next_self_record;
MainChainNodeType() = delete;
explicit MainChainNodeType(frame_id_t frame_id, size_t time_stamp, MainChainNodeType *prev, MainChainNodeType *next,
MainChainNodeType *next_self_record)
: frame_id(frame_id), time_stamp(time_stamp), prev(prev), next(next), next_self_record(next_self_record) {}
};
template <typename ListNodeType>
inline void RemoveFromList(ListNodeType *node) {
if (node->prev != nullptr) {
node->prev->next = node->next;
}
if (node->next != nullptr) {
node->next->prev = node->prev;
}
}
template <typename ListNodeType>
inline void InsertAt(ListNodeType *node, ListNodeType *prev, ListNodeType *next) {
node->prev = prev;
node->next = next;
if (prev != nullptr) prev->next = node;
if (next != nullptr) next->prev = node;
}
struct LRUKRecord {
LRUKRecord() = default;
bool evitable;
size_t visit_count;
bool active;
MainChainNodeType *head_node_in_main_chain, *tail_node_in_main_chain;
LRUChainNodeType *node_in_LRU_chain;
};
void RemoveWholeFrameFromLRUKChain(MainChainNodeType *first_occurrence_ptr); // remove and delete nodes
MainChainNodeType *AddRecordToMainChain(frame_id_t frame_it, size_t time_stamp,
MainChainNodeType *last_node_in_main_chain);
LRUChainNodeType *LRU_chain_head_guard, *LRU_chain_tail_guard;
MainChainNodeType *LRUK_chain_head_guard, *LRUK_chain_tail_guard;
size_t current_timestamp_{0};
size_t current_evitable_count_{0};
size_t max_frame_count;
size_t k_value;
std::mutex latch;
LRUKRecord *hash_for_record;
};
#endif