2021-10-11 22:05:45 +08:00
|
|
|
//
|
|
|
|
// Created by YuhangQ on 2021/9/24.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "page_manager.h"
|
2021-11-03 11:14:34 +08:00
|
|
|
#include "btree/list.h"
|
|
|
|
|
2021-11-05 23:15:09 +08:00
|
|
|
|
2021-10-11 22:05:45 +08:00
|
|
|
|
|
|
|
int PageManager::loadDatabase(const char *filename) {
|
|
|
|
Instance().stream.open(filename);
|
2021-11-03 11:14:34 +08:00
|
|
|
Instance().stream.seekp(0, std::ios::end);
|
|
|
|
int index = Instance().stream.tellp() / 1024;
|
|
|
|
if(index == 0) {
|
|
|
|
StoragePage(0).save();
|
|
|
|
StoragePage(1).save();
|
|
|
|
StoragePage(2).save();
|
|
|
|
}
|
2021-10-11 22:05:45 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-11-05 23:15:09 +08:00
|
|
|
std::shared_ptr<StoragePage> PageManager::getPage(const int &index) {
|
2021-11-03 09:39:13 +08:00
|
|
|
|
|
|
|
if(cache.exist(index)) {
|
|
|
|
return cache.get(index);
|
|
|
|
}
|
|
|
|
|
2021-11-05 23:15:09 +08:00
|
|
|
auto page = std::make_shared<StoragePage>(index);
|
2021-10-11 22:05:45 +08:00
|
|
|
// 调整指针位置
|
|
|
|
stream.clear();
|
2021-11-05 23:15:09 +08:00
|
|
|
stream.seekg((long long)index * 1024);
|
|
|
|
stream.read(*page, 1024);
|
2021-10-11 22:05:45 +08:00
|
|
|
return page;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageManager::setPage(const int &index, const StoragePage &page) {
|
2021-11-05 23:15:09 +08:00
|
|
|
cache.put(index, std::make_shared<StoragePage>(page));
|
|
|
|
|
2021-10-11 22:05:45 +08:00
|
|
|
stream.clear();
|
2021-11-05 23:15:09 +08:00
|
|
|
stream.seekg((long long)index * 1024);
|
2021-10-11 22:05:45 +08:00
|
|
|
stream.write(page, 1024);
|
|
|
|
}
|
|
|
|
|
2021-10-23 16:28:57 +08:00
|
|
|
int PageManager::allocate() {
|
2021-11-05 23:15:09 +08:00
|
|
|
|
|
|
|
// try to allocate from free block list
|
|
|
|
auto page = getPage(0);
|
|
|
|
int index = page->getIntStartFrom(0);
|
|
|
|
if(index != 0) {
|
|
|
|
auto allocatePage = getPage(index);
|
|
|
|
|
|
|
|
page->setIntStartFrom(0, allocatePage->next());
|
|
|
|
// reset
|
|
|
|
allocatePage->clear();
|
|
|
|
allocatePage->save();
|
|
|
|
page->save();
|
|
|
|
//printf("allocate: %d\n", index);
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// allocate block at the end
|
2021-10-23 16:28:57 +08:00
|
|
|
stream.seekp(0, std::ios::end);
|
2021-11-05 23:15:09 +08:00
|
|
|
index = stream.tellp() / 1024;
|
2021-10-23 16:28:57 +08:00
|
|
|
setPage(index, StoragePage(index));
|
|
|
|
return index;
|
2021-10-11 22:05:45 +08:00
|
|
|
}
|
2021-10-31 14:51:09 +08:00
|
|
|
|
2021-11-03 11:14:34 +08:00
|
|
|
void PageManager::release(const int &index, const bool &next) {
|
2021-11-05 23:15:09 +08:00
|
|
|
auto page = getPage(0);
|
|
|
|
int head = page->getIntStartFrom(0);
|
|
|
|
auto releasePage = getPage(index);
|
|
|
|
releasePage->setNext(head);
|
|
|
|
page->setIntStartFrom(0, releasePage->getAddress());
|
|
|
|
page->save();
|
|
|
|
releasePage->save();
|
|
|
|
//printf("release: %d\n", index);
|
2021-11-03 22:05:13 +08:00
|
|
|
|
2021-10-31 14:51:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
nlohmann::json PageManager::readJSONFromFile(const int &index) {
|
|
|
|
std::string content;
|
|
|
|
|
2021-11-05 23:15:09 +08:00
|
|
|
auto page = getPage(index);
|
2021-10-31 14:51:09 +08:00
|
|
|
while(true) {
|
|
|
|
for(int i=0; i<1016; i++) {
|
2021-11-05 23:15:09 +08:00
|
|
|
if((*page)[i] == '\0') break;
|
|
|
|
content.push_back((*page)[i]);
|
2021-10-31 14:51:09 +08:00
|
|
|
}
|
2021-11-05 23:15:09 +08:00
|
|
|
if(page->next() == 0) break;
|
|
|
|
page = getPage(page->next());
|
2021-10-31 14:51:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return nlohmann::json::parse(content);
|
|
|
|
}
|
|
|
|
|
|
|
|
int PageManager::saveJSONToFile(const nlohmann::json& json) {
|
|
|
|
std::string content = json.dump();
|
|
|
|
int size = content.size();
|
|
|
|
|
2021-11-05 23:15:09 +08:00
|
|
|
auto page = getPage(allocate());
|
|
|
|
int res = page->getAddress();
|
2021-10-31 14:51:09 +08:00
|
|
|
int p = 0;
|
|
|
|
while(p < size) {
|
|
|
|
int len = std::min(size - p, 1016);
|
2021-11-05 23:15:09 +08:00
|
|
|
page->setStartFrom(0, &content.c_str()[p], len);
|
|
|
|
page->save();
|
2021-10-31 14:51:09 +08:00
|
|
|
p += len;
|
|
|
|
if(p < size) {
|
|
|
|
int newPage = allocate();
|
2021-11-05 23:15:09 +08:00
|
|
|
int lastPage = page->getAddress();
|
|
|
|
page->setNext(newPage);
|
|
|
|
page->save();
|
2021-10-31 14:51:09 +08:00
|
|
|
page = getPage(newPage);
|
2021-11-05 23:15:09 +08:00
|
|
|
page->setLast(lastPage);
|
|
|
|
page->save();
|
2021-10-31 14:51:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|