finish test for basic tools

This commit is contained in:
2024-04-26 13:44:54 +00:00
parent 39dffd88cd
commit 460245ff5e
2 changed files with 19 additions and 66 deletions

View File

@ -16,27 +16,16 @@ using std::string;
template <class T, int info_len = 2> template <class T, int info_len = 2>
class MemoryRiver { class MemoryRiver {
private: private:
struct ElementPair {
T data;
size_t nxt_blank;
};
const static size_t max_element_in_page = (4096 - sizeof(size_t)) / sizeof(ElementPair);
struct DataType {
size_t elements_count;
ElementPair elements[max_element_in_page];
};
union Page { union Page {
DataType dat; T data;
char filler[4096]; char filler[4096];
}; };
// data_id = frame_id * max_element_in_page + element_id
std::string file_name; std::string file_name;
DiskManager *disk_manager; DiskManager *disk_manager;
BufferPoolManager *bpm; BufferPoolManager *bpm;
size_t first_blank_element_pair_id;
char *raw_mem; char *raw_mem;
static_assert(info_len * sizeof(int) <= 4000, "info_len should be less than 4000"); static_assert(info_len * sizeof(int) <= 4000, "info_len should be less than 4000");
static_assert(sizeof(T) <= 4088, "T should be less than 4088"); static_assert(sizeof(T) <= 4096, "T should be less than 4096");
public: public:
MemoryRiver() : disk_manager(nullptr), bpm(nullptr), file_name("") {} MemoryRiver() : disk_manager(nullptr), bpm(nullptr), file_name("") {}
@ -45,10 +34,8 @@ class MemoryRiver {
disk_manager = new DiskManager(file_name); disk_manager = new DiskManager(file_name);
bpm = new BufferPoolManager(100, 5, disk_manager); bpm = new BufferPoolManager(100, 5, disk_manager);
raw_mem = bpm->RawDataMemory(); raw_mem = bpm->RawDataMemory();
memcpy(&first_blank_element_pair_id, raw_mem, sizeof(size_t));
} }
void CloseFile() { void CloseFile() {
memcpy(raw_mem, &first_blank_element_pair_id, sizeof(size_t));
bpm->FlushAllPages(); bpm->FlushAllPages();
file_name = ""; file_name = "";
delete bpm; delete bpm;
@ -62,84 +49,50 @@ class MemoryRiver {
void initialise(string FN = "") { void initialise(string FN = "") {
if (file_name != "") { if (file_name != "") {
std::string name_bak = file_name; std::string name_bak=file_name;
CloseFile(); CloseFile();
file_name = name_bak; file_name = name_bak;
} }
if (FN != "") file_name = FN; if (FN != "") file_name = FN;
if (file_name == "") return; if (file_name == "") return;
disk_manager = new DiskManager(file_name, true); disk_manager = new DiskManager(file_name);
bpm = new BufferPoolManager(100, 5, disk_manager); bpm = new BufferPoolManager(100, 5, disk_manager);
raw_mem = bpm->RawDataMemory(); raw_mem = bpm->RawDataMemory();
memset(raw_mem, 0, bpm->RawDatMemorySize()); memset(raw_mem, 0, bpm->RawDatMemorySize());
first_blank_element_pair_id = 0;
} }
void get_info(int &tmp, int n) { void get_info(int &tmp, int n) {
if (n > info_len) return; if (n > info_len) return;
n += 2; n--;
memcpy(&tmp, raw_mem + n * sizeof(int), sizeof(int)); memcpy(&tmp, raw_mem + n * sizeof(int), sizeof(int));
} }
void write_info(int tmp, int n) { void write_info(int tmp, int n) {
if (n > info_len) return; if (n > info_len) return;
n += 2; n--;
memcpy(raw_mem + n * sizeof(int), &tmp, sizeof(int)); memcpy(raw_mem + n * sizeof(int), &tmp, sizeof(int));
} }
int write(T &t) { int write(T &t) {
size_t element_id = first_blank_element_pair_id; frame_id_t frame_id;
size_t res_id = 0; BasicPageGuard guard = bpm->NewPageGuarded(&frame_id);
if (element_id != 0) { guard.AsMut<Page>()->data = t;
res_id = element_id; return frame_id;
frame_id_t frame_id = element_id / max_element_in_page;
element_id %= max_element_in_page;
WritePageGuard guard = bpm->FetchPageWrite(frame_id);
first_blank_element_pair_id = guard.AsMut<Page>()->dat.elements[element_id].nxt_blank;
guard.AsMut<Page>()->dat.elements[element_id].data = t;
guard.AsMut<Page>()->dat.elements_count++;
} else {
frame_id_t frame_id;
BasicPageGuard guard = bpm->NewPageGuarded(&frame_id);
guard.AsMut<Page>()->dat.elements[0].data = t;
element_id = frame_id * max_element_in_page;
res_id = element_id;
if (max_element_in_page > 1) first_blank_element_pair_id = element_id + 1;
for (size_t i = 1; i < max_element_in_page - 1; i++) {
guard.AsMut<Page>()->dat.elements[i].nxt_blank = element_id + i + 1;
}
guard.AsMut<Page>()->dat.elements[max_element_in_page - 1].nxt_blank = 0;
guard.AsMut<Page>()->dat.elements_count = 1;
}
return res_id;
} }
void update(T &t, const int index) { void update(T &t, const int index) {
size_t frame_id = index / max_element_in_page; WritePageGuard guard = bpm->FetchPageWrite(index);
WritePageGuard guard = bpm->FetchPageWrite(frame_id); guard.AsMut<Page>()->data = t;
guard.AsMut<Page>()->dat.elements[index % max_element_in_page].data = t;
} }
//读出位置索引index对应的T对象的值并赋值给t保证调用的index都是由write函数产生 //读出位置索引index对应的T对象的值并赋值给t保证调用的index都是由write函数产生
void read(T &t, const int index) { void read(T &t, const int index) {
size_t frame_id = index / max_element_in_page; ReadPageGuard guard = bpm->FetchPageRead(index);
ReadPageGuard guard = bpm->FetchPageRead(frame_id); t = guard.As<Page>()->data;
t = guard.As<Page>()->dat.elements[index % max_element_in_page].data;
} }
//删除位置索引index对应的对象(不涉及空间回收时,可忽略此函数)保证调用的index都是由write函数产生 //删除位置索引index对应的对象(不涉及空间回收时,可忽略此函数)保证调用的index都是由write函数产生
void Delete(int index) { void Delete(int index) { bpm->DeletePage(index); }
size_t frame_id = index / max_element_in_page;
WritePageGuard guard = bpm->FetchPageWrite(frame_id);
size_t element_id = index % max_element_in_page;
guard.AsMut<Page>()->dat.elements[element_id].nxt_blank = first_blank_element_pair_id;
first_blank_element_pair_id = index;
guard.AsMut<Page>()->dat.elements_count--;
// if (guard.AsMut<Page>()->dat.elements_count == 0) {
// guard.Drop();
// bpm->DeletePage(frame_id);
// }
}
}; };
#endif // BPT_MEMORYRIVER_HPP #endif // BPT_MEMORYRIVER_HPP

View File

@ -254,14 +254,14 @@ class FixLengthString {
bool operator==(const FixLengthString &other) const { return memcmp(data, other.data, length) == 0; } bool operator==(const FixLengthString &other) const { return memcmp(data, other.data, length) == 0; }
}; };
TEST(MemoryRiver, T2) { TEST(MemoryRiver, T2) {
spdlog::set_level(spdlog::level::debug); spdlog::set_level(spdlog::level::err);
auto logger_ptr = spdlog::stderr_color_mt("stderr_logger"); auto logger_ptr = spdlog::stderr_color_mt("stderr_logger");
const static size_t string_len = 5; const static size_t string_len = 120;
typedef FixLengthString<string_len> DataType; typedef FixLengthString<string_len> DataType;
std::deque<size_t> index_collection; std::deque<size_t> index_collection;
std::unordered_map<size_t, std::pair<int, int>> index_track; std::unordered_map<size_t, std::pair<int, int>> index_track;
size_t interal_id_tot = 0; size_t interal_id_tot = 0;
const unsigned int RndSeed = 3794; // testing::GTEST_FLAG(random_seed); const unsigned int RndSeed = testing::GTEST_FLAG(random_seed);
std::mt19937 rnd(RndSeed); std::mt19937 rnd(RndSeed);
remove("/tmp/T2.std"); remove("/tmp/T2.std");
remove("/tmp/T2.dat"); remove("/tmp/T2.dat");
@ -269,7 +269,7 @@ TEST(MemoryRiver, T2) {
{ {
sol::MemoryRiver<DataType, kInfoLength> STD("/tmp/T2.std"); sol::MemoryRiver<DataType, kInfoLength> STD("/tmp/T2.std");
MemoryRiver<DataType, kInfoLength> mr("/tmp/T2.dat"); MemoryRiver<DataType, kInfoLength> mr("/tmp/T2.dat");
int total_opts = 5; int total_opts = 1000;
while (total_opts-- > 0) { while (total_opts-- > 0) {
int opt = rnd() % 6; int opt = rnd() % 6;
switch (opt) { switch (opt) {