mirror of
https://github.com/YuhangQ/InvoDB.git
synced 2025-01-26 22:50:56 +00:00
创建 collection
This commit is contained in:
parent
2c318faf40
commit
6cb59287d7
@ -3,8 +3,12 @@ project(InvoDB)
|
|||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
include_directories(/opt/homebrew/Cellar/boost/1.76.0/include)
|
||||||
include_directories(.)
|
include_directories(.)
|
||||||
|
include_directories(./invodb)
|
||||||
|
|
||||||
add_executable(InvoDB
|
add_executable(InvoDB
|
||||||
invodb/main.cpp
|
invodb/main.cpp
|
||||||
invodb/main.h invodb/file/page_manager.cpp invodb/file/page_manager.h invodb/file/virtual_storage.cpp invodb/file/virtual_storage.h invodb/models/json.cpp invodb/models/json.h invodb/invodb.cpp invodb/invodb.h invodb/models/collection.cpp invodb/models/collection.h)
|
invodb/main.h invodb/file/page_manager.cpp invodb/file/page_manager.h invodb/models/json.cpp invodb/models/json.h invodb/invodb.cpp invodb/invodb.h invodb/models/collection.cpp invodb/models/collection.h invodb/file/storage_page.cpp invodb/file/storage_page.h invodb/utils/logger.h invodb/utils/uuid.h)
|
||||||
|
@ -10,7 +10,7 @@ int PageManager::loadDatabase(const char *filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StoragePage PageManager::getPage(const int &index) {
|
StoragePage PageManager::getPage(const int &index) {
|
||||||
StoragePage page;
|
StoragePage page(index);
|
||||||
// 调整指针位置
|
// 调整指针位置
|
||||||
stream.clear();
|
stream.clear();
|
||||||
stream.seekg(index * 1024);
|
stream.seekg(index * 1024);
|
||||||
@ -24,29 +24,9 @@ void PageManager::setPage(const int &index, const StoragePage &page) {
|
|||||||
stream.write(page, 1024);
|
stream.write(page, 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StoragePage::print() {
|
int PageManager::allocate() {
|
||||||
for(int i=0; i<16; i++) {
|
stream.seekp(0, std::ios::end);
|
||||||
for(int j=0; j<256; j++) {
|
int index = stream.tellp() / 1024;
|
||||||
printf("%u ", page[i * 16 + j]);
|
setPage(index, StoragePage(index));
|
||||||
}
|
return index;
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取下一个连接的页,返回零则到达链结尾
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
int StoragePage::next() {
|
|
||||||
return *((const int *)&page[1020]);
|
|
||||||
}
|
|
||||||
|
|
||||||
int StoragePage::setNext(const int &nextPage) {
|
|
||||||
*((int *)&page[1020]) = nextPage;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int *StoragePage::intArray() {
|
|
||||||
return (int *)page;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -7,21 +7,8 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
class StoragePage {
|
#include "storage_page.h"
|
||||||
public:
|
|
||||||
void print();
|
|
||||||
int next();
|
|
||||||
int setNext(const int& nextPage);
|
|
||||||
int* intArray();
|
|
||||||
StoragePage() { memset(page, 0, sizeof(page)); }
|
|
||||||
char& operator[] (int index) { return this->page[index]; }
|
|
||||||
operator const char *() const { return this->page; }
|
|
||||||
operator char *() { return this->page; }
|
|
||||||
private:
|
|
||||||
char page[1024];
|
|
||||||
};
|
|
||||||
|
|
||||||
class PageManager {
|
class PageManager {
|
||||||
public:
|
public:
|
||||||
@ -33,10 +20,9 @@ public:
|
|||||||
StoragePage getPage(const int &index);
|
StoragePage getPage(const int &index);
|
||||||
void setPage(const int &index, const StoragePage &page);
|
void setPage(const int &index, const StoragePage &page);
|
||||||
int allocate();
|
int allocate();
|
||||||
|
void free(const int &index);
|
||||||
private:
|
private:
|
||||||
std::fstream stream;
|
std::fstream stream;
|
||||||
|
|
||||||
// 私有化实现单例
|
// 私有化实现单例
|
||||||
PageManager() {}
|
PageManager() {}
|
||||||
~PageManager() {}
|
~PageManager() {}
|
||||||
|
56
invodb/file/storage_page.cpp
Normal file
56
invodb/file/storage_page.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// Created by YuhangQ on 2021/10/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "storage_page.h"
|
||||||
|
#include "page_manager.h"
|
||||||
|
|
||||||
|
|
||||||
|
void StoragePage::print() {
|
||||||
|
printf("-------------------PageInfo--------------------\n");
|
||||||
|
for(int i=0; i<8; i++) {
|
||||||
|
for(int j=0; j<32; j++) {
|
||||||
|
printf("%u ", intArray()[i*32+j]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int StoragePage::next() {
|
||||||
|
return getIntStartFrom(1020);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoragePage::setNext(const int& nextPage) {
|
||||||
|
setIntStartFrom(1020, nextPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
int StoragePage::last() {
|
||||||
|
return getIntStartFrom(1016);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoragePage::setLast(const int& lastPage) {
|
||||||
|
setIntStartFrom(1016, lastPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
int *StoragePage::intArray() {
|
||||||
|
return (int *)page;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StoragePage::getIntStartFrom(const int& index) {
|
||||||
|
return *((const int *)&page[index]);
|
||||||
|
}
|
||||||
|
void StoragePage::setIntStartFrom(const int& index, const int& value) {
|
||||||
|
*((int *)&page[index]) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoragePage::setStringStartFrom(const int &index, const char *str) {
|
||||||
|
for(int i=0; i<strlen(str); i++) {
|
||||||
|
page[index+i] = str[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void StoragePage::save() {
|
||||||
|
PageManager::Instance().setPage(address, *this);
|
||||||
|
}
|
||||||
|
|
36
invodb/file/storage_page.h
Normal file
36
invodb/file/storage_page.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// Created by YuhangQ on 2021/10/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef INVODB_STORAGE_PAGE_H
|
||||||
|
#define INVODB_STORAGE_PAGE_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
|
class PageManager;
|
||||||
|
|
||||||
|
class StoragePage {
|
||||||
|
public:
|
||||||
|
void print();
|
||||||
|
int next();
|
||||||
|
void setNext(const int& nextPage);
|
||||||
|
int last();
|
||||||
|
void setLast(const int& lastPage);
|
||||||
|
void save();
|
||||||
|
int getIntStartFrom(const int &index);
|
||||||
|
void setIntStartFrom(const int &index, const int &value);
|
||||||
|
void setStringStartFrom(const int &index, const char *str);
|
||||||
|
int *intArray();
|
||||||
|
StoragePage(const int& id) { memset(page, 0, sizeof(page)); }
|
||||||
|
char& operator[] (int index) { return this->page[index]; }
|
||||||
|
operator const char *() const { return this->page; }
|
||||||
|
operator char *() { return this->page; }
|
||||||
|
private:
|
||||||
|
char page[1024];
|
||||||
|
int address;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //INVODB_STORAGE_PAGE_H
|
@ -1,47 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by YuhangQ on 2021/9/30.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "virtual_storage.h"
|
|
||||||
|
|
||||||
int VirtualStorage::loadDatabase(const char *filename) {
|
|
||||||
int result = PageManager::loadDatabase(filename);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
StoragePage VirtualStorage::getPage(const int &index) {
|
|
||||||
PageManager& manager = PageManager::Instance();
|
|
||||||
return manager.getPage(getPhysicalAddress(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualStorage::setPage(const int &index, const StoragePage &page) {
|
|
||||||
PageManager& manager = PageManager::Instance();
|
|
||||||
manager.setPage(getPhysicalAddress(index), page);
|
|
||||||
}
|
|
||||||
|
|
||||||
int VirtualStorage::getPhysicalAddress(const int &index) {
|
|
||||||
loadPageInfoTable(index >> 2);
|
|
||||||
return (table[index >> 2].addr << 2) || (index & 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
int VirtualStorage::getNextAddress(const int &index) {
|
|
||||||
loadPageInfoTable(index >> 2);
|
|
||||||
return table[index >> 2].next;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VirtualStorage::loadPageInfoTable(const int &index) {
|
|
||||||
PageManager& manager = PageManager::Instance();
|
|
||||||
// 未命中 cache
|
|
||||||
if(table.count(index) == 0) {
|
|
||||||
int pageIndex = 1 + index / 512;
|
|
||||||
// 加载页表
|
|
||||||
StoragePage page = manager.getPage(pageIndex);
|
|
||||||
int *arr = page.intArray();
|
|
||||||
for(int i=0; i<512; i++) {
|
|
||||||
table[(pageIndex - 1) * 512 + i] = TableEl{ arr[2*i], arr[2*i+1] };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by YuhangQ on 2021/9/30.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef INVODB_VIRTUAL_STORAGE_H
|
|
||||||
#define INVODB_VIRTUAL_STORAGE_H
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include "page_manager.h"
|
|
||||||
|
|
||||||
class VirtualStorage {
|
|
||||||
public:
|
|
||||||
static VirtualStorage& Instance() {
|
|
||||||
static VirtualStorage instance;
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
static int loadDatabase(const char *filename);
|
|
||||||
StoragePage getPage(const int &index);
|
|
||||||
void setPage(const int &index, const StoragePage &page);
|
|
||||||
int allocate();
|
|
||||||
private:
|
|
||||||
struct TableEl {
|
|
||||||
int addr;
|
|
||||||
int next;
|
|
||||||
};
|
|
||||||
// 页表 Cache
|
|
||||||
std::map<int, TableEl> table;
|
|
||||||
int getPhysicalAddress(const int &index);
|
|
||||||
int getNextAddress(const int &index);
|
|
||||||
void loadPageInfoTable(const int &index);
|
|
||||||
// 私有化实现单例
|
|
||||||
VirtualStorage() {}
|
|
||||||
~VirtualStorage() {}
|
|
||||||
VirtualStorage(const PageManager&);
|
|
||||||
VirtualStorage& operator=(const PageManager&);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //INVODB_VIRTUAL_STORAGE_H
|
|
@ -5,12 +5,17 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
VirtualStorage::loadDatabase("test.invodb");
|
PageManager::loadDatabase("test.invodb");
|
||||||
VirtualStorage& storage = VirtualStorage::Instance();
|
Collection::loadCollections();
|
||||||
|
|
||||||
|
PageManager& manager = PageManager::Instance();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Collection &col = Collection::getCollection("hello");
|
||||||
|
|
||||||
|
JSON json("{\"hello\": 1}");
|
||||||
|
col.insert(json);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -6,7 +6,6 @@
|
|||||||
#define INVODB_MAIN_H
|
#define INVODB_MAIN_H
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "file/virtual_storage.h"
|
#include "models/collection.h"
|
||||||
#include "invodb/models/json.h"
|
|
||||||
|
|
||||||
#endif //INVODB_MAIN_H
|
#endif //INVODB_MAIN_H
|
||||||
|
@ -3,3 +3,84 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "collection.h"
|
#include "collection.h"
|
||||||
|
#include "utils/uuid.h"
|
||||||
|
|
||||||
|
Collection::Collection(const std::string &name, const int &firstPage) {
|
||||||
|
Logger::info<std::string, std::string>("load Collection: ", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collection::insert(JSON &json) {
|
||||||
|
|
||||||
|
if(!json.HasMember(" __Invo_ID__")) {
|
||||||
|
std::string uuid = generateUUID();
|
||||||
|
Document::AllocatorType &allocator = json.GetAllocator();
|
||||||
|
Value invoid (kStringType);
|
||||||
|
invoid.SetString(uuid.c_str(), uuid.size());
|
||||||
|
json.AddMember(" __Invo_ID__", invoid, allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::info<std::string>(json.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::map<std::string, Collection*> Collection::map;
|
||||||
|
std::set<int> Collection::free;
|
||||||
|
|
||||||
|
void Collection::loadCollections() {
|
||||||
|
// 前四页为集合信息页
|
||||||
|
for (int id = 0; id < 4; id++) {
|
||||||
|
StoragePage page = PageManager::Instance().getPage(id);
|
||||||
|
PageManager::Instance().setPage(id, page);
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
int p = i * 32;
|
||||||
|
int len = strlen(&page[p]);
|
||||||
|
std::string name(&page[p], len > 28 ? 28 : len);
|
||||||
|
int firstPage = page.getIntStartFrom(p + 28);
|
||||||
|
// if free
|
||||||
|
if (firstPage == 0) free.insert(id * 32 + i);
|
||||||
|
// not free
|
||||||
|
else map.insert(make_pair(name, new Collection(name, firstPage)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Logger::info<std::string, int>("Successfully load Collections: ", 128 - free.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection& Collection::createCollection(const std::string &name) {
|
||||||
|
// exist
|
||||||
|
if(map.count(name) != 0) {
|
||||||
|
throw "collection has already exist";
|
||||||
|
}
|
||||||
|
// no free line
|
||||||
|
if(free.size() == 0) {
|
||||||
|
throw "you are reach the max limit count of collections";
|
||||||
|
}
|
||||||
|
int id = *free.begin();
|
||||||
|
free.erase(free.begin());
|
||||||
|
|
||||||
|
StoragePage page = PageManager::Instance().getPage(id / 32);
|
||||||
|
id %= 32;
|
||||||
|
|
||||||
|
int collectionPage = PageManager::Instance().allocate();
|
||||||
|
|
||||||
|
if(name.size() > 28) {
|
||||||
|
throw "too long name of collection";
|
||||||
|
}
|
||||||
|
|
||||||
|
page.setStringStartFrom(id*32, name.c_str());
|
||||||
|
page.setIntStartFrom(id*32+28, collectionPage);
|
||||||
|
page.save();
|
||||||
|
|
||||||
|
Collection *col = new Collection(name, collectionPage);
|
||||||
|
|
||||||
|
map.insert(make_pair(name, col));
|
||||||
|
|
||||||
|
return *col;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection &Collection::getCollection(const std::string &name) {
|
||||||
|
if(map.count(name) == 0) {
|
||||||
|
throw "no such collection";
|
||||||
|
}
|
||||||
|
return *map[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,28 @@
|
|||||||
#ifndef INVODB_COLLECTION_H
|
#ifndef INVODB_COLLECTION_H
|
||||||
#define INVODB_COLLECTION_H
|
#define INVODB_COLLECTION_H
|
||||||
|
|
||||||
|
#include "file/page_manager.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
#include "json.h"
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
class Collection {
|
class Collection {
|
||||||
|
public:
|
||||||
|
static void insert(JSON &json);
|
||||||
|
static void loadCollections();
|
||||||
|
static Collection& getCollection(const std::string& name);
|
||||||
|
static Collection& createCollection(const std::string& name);
|
||||||
|
private:
|
||||||
|
static std::map<std::string, Collection*> map;
|
||||||
|
static std::set<int> free;
|
||||||
|
Collection(const std::string& name,const int& firstPage);
|
||||||
|
Collection() {}
|
||||||
|
~Collection() {}
|
||||||
|
Collection(const Collection&);
|
||||||
|
Collection& operator=(const Collection&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,4 +2,11 @@
|
|||||||
// Created by YuhangQ on 2021/10/9.
|
// Created by YuhangQ on 2021/10/9.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
|
|
||||||
|
std::string JSON::ToString() {
|
||||||
|
StringBuffer buffer;
|
||||||
|
Writer<StringBuffer> writer(buffer);
|
||||||
|
this->Accept(writer);
|
||||||
|
return buffer.GetString();
|
||||||
|
}
|
||||||
|
@ -7,11 +7,18 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "rapidjson/document.h"
|
#include "rapidjson/document.h"
|
||||||
|
#include "rapidjson/writer.h"
|
||||||
|
#include "rapidjson/stringbuffer.h"
|
||||||
|
|
||||||
using namespace rapidjson;
|
using namespace rapidjson;
|
||||||
|
|
||||||
class JSON : public Document {
|
class JSON : public Document {
|
||||||
|
public:
|
||||||
|
JSON(std::string json): Document() { this->Parse(json.c_str()); }
|
||||||
|
JSON(const char *json): Document() { this->Parse(json); }
|
||||||
|
|
||||||
|
std::string ToString();
|
||||||
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
59
invodb/utils/logger.h
Normal file
59
invodb/utils/logger.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
//
|
||||||
|
// Created by YuhangQ on 2021/10/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef INVODB_LOGGER_H
|
||||||
|
#define INVODB_LOGGER_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Logger {
|
||||||
|
public:
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static void info(const T& msg);
|
||||||
|
|
||||||
|
template<typename T, typename K>
|
||||||
|
static void info(const T& first, const K& second);
|
||||||
|
template<typename T>
|
||||||
|
static void warn(const T& msg);
|
||||||
|
template<typename T, typename K>
|
||||||
|
static void warn(const T& first, const K& second);
|
||||||
|
template<typename T>
|
||||||
|
static void error(const T& msg);
|
||||||
|
template<typename T, typename K>
|
||||||
|
static void error(const T& first, const K& second);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void Logger::info(const T &msg) {
|
||||||
|
std::cout << "[INFO] " << msg << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename K>
|
||||||
|
void Logger::info(const T &first, const K &second) {
|
||||||
|
std::cout << "[INFO] " << first << second << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void Logger::warn(const T &msg) {
|
||||||
|
std::cout << "[WARN] " << msg << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename K>
|
||||||
|
void Logger::warn(const T &first, const K &second) {
|
||||||
|
std::cout << "[WARN] " << first << second << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void Logger::error(const T &msg) {
|
||||||
|
std::cout << "[ERROR] " << msg << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename K>
|
||||||
|
void Logger::error(const T &first, const K &second) {
|
||||||
|
std::cout << "[ERROR] " << first << second << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //INVODB_LOGGER_H
|
22
invodb/utils/uuid.h
Normal file
22
invodb/utils/uuid.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// Created by YuhangQ on 2021/10/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef INVODB_UUID_H
|
||||||
|
#define INVODB_UUID_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <boost/uuid/uuid.hpp>
|
||||||
|
#include <boost/uuid/uuid_io.hpp>
|
||||||
|
#include <boost/uuid/uuid_generators.hpp>
|
||||||
|
|
||||||
|
std::string generateUUID() {
|
||||||
|
boost::uuids::uuid a_uuid = boost::uuids::random_generator()();
|
||||||
|
std::string uuid_string = boost::uuids::to_string(a_uuid);
|
||||||
|
std::remove(uuid_string.begin(), uuid_string.end(), '-');
|
||||||
|
uuid_string.resize(32);
|
||||||
|
return uuid_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //INVODB_UUID_H
|
Loading…
x
Reference in New Issue
Block a user