mirror of
https://github.com/YuhangQ/InvoDB.git
synced 2025-01-25 22:20:58 +00:00
适配 nodejs
This commit is contained in:
parent
c49cb450ce
commit
458ab0649a
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
test.invodb
|
||||
/cmake-build-debug/
|
||||
.idea
|
||||
package-lock.json
|
||||
*.invodb
|
||||
.vscode
|
||||
node_modules
|
||||
build
|
8
.idea/.gitignore
generated
vendored
8
.idea/.gitignore
generated
vendored
@ -1,8 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
1
.idea/.name
generated
1
.idea/.name
generated
@ -1 +0,0 @@
|
||||
InvoDB
|
2
.idea/InvoDB.iml
generated
2
.idea/InvoDB.iml
generated
@ -1,2 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
4
.idea/misc.xml
generated
4
.idea/misc.xml
generated
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||
</project>
|
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/InvoDB.iml" filepath="$PROJECT_DIR$/.idea/InvoDB.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -1,14 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.16.3)
|
||||
project(InvoDB)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0")
|
||||
|
||||
include_directories(.)
|
||||
include_directories(./invodb)
|
||||
|
||||
add_executable(InvoDB
|
||||
invodb/main.cpp
|
||||
invodb/main.h invodb/file/page_manager.cpp invodb/file/page_manager.h invodb/collection/collection.cpp invodb/collection/collection.h invodb/file/storage_page.cpp invodb/file/storage_page.h invodb/utils/logger.h invodb/utils/uuid.h invodb/btree/node.h invodb/btree/btree.h invodb/btree/list.h invodb/collection/query.cpp invodb/utils/cache.h invodb/collection/index.cpp)
|
27
binding.gyp
Normal file
27
binding.gyp
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "core",
|
||||
"sources": [
|
||||
"./src/collection/collection.cpp",
|
||||
"./src/collection/index.cpp",
|
||||
"./src/collection/query.cpp",
|
||||
"./src/file/page_manager.cpp",
|
||||
"./src/file/storage_page.cpp",
|
||||
"./src/main.cpp",
|
||||
],
|
||||
"include_dirs": [
|
||||
"<!@(node -p \"require('node-addon-api').include\")"
|
||||
],
|
||||
"dependencies": [
|
||||
"<!(node -p \"require('node-addon-api').gyp\")"
|
||||
],
|
||||
"cflags!": ["-fno-exceptions"],
|
||||
"cflags_cc!": ["-fno-exceptions"],
|
||||
"defines": ["NAPI_CPP_EXCEPTIONS"],
|
||||
"xcode_settings": {
|
||||
"GCC_ENABLE_CPP_EXCEPTIONS": "YES"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
21
demo/test.js
Normal file
21
demo/test.js
Normal file
@ -0,0 +1,21 @@
|
||||
const invodb = require('..')
|
||||
|
||||
invodb.database('zzz.invodb')
|
||||
|
||||
let col = invodb.colection('blog')
|
||||
if(!col.exist()) col.create();
|
||||
|
||||
col.insert({ id: 1, title: "第一篇文章", author: "YuhangQ"})
|
||||
col.insert({ id: 2, title: "第二篇文章", author: "Ciel"})
|
||||
col.insert({ id: 3, title: "第三篇文章", author: "YuhangQ"})
|
||||
col.insert({ id: 4, title: "第四篇文章", author: "By"})
|
||||
|
||||
let result = col.query({
|
||||
id: {
|
||||
$gte: 2,
|
||||
$lte: 3
|
||||
},
|
||||
author: "YuhangQ"
|
||||
})
|
||||
|
||||
console.log(result)
|
38
index.js
Normal file
38
index.js
Normal file
@ -0,0 +1,38 @@
|
||||
const core = require("./build/Release/core.node");
|
||||
|
||||
function database(filename) {
|
||||
core.database(filename);
|
||||
}
|
||||
|
||||
function colection(collectionName) {
|
||||
function exist() { return core.exists(collectionName); }
|
||||
function create() { core.create(collectionName); }
|
||||
function insert(object) {
|
||||
if(!core.exists(collectionName)) throw `Collection ${collectionName} doesn't exists!`;
|
||||
let json = JSON.stringify(object);
|
||||
core.insert(collectionName, json);
|
||||
}
|
||||
function remove(object) {
|
||||
if(!core.exists(collectionName)) throw `Collection ${collectionName} doesn't exists!`;
|
||||
let json = JSON.stringify(object);
|
||||
core.remove(collectionName, json);
|
||||
}
|
||||
function query(object) {
|
||||
if(!core.exists(collectionName)) throw `Collection ${collectionName} doesn't exists!`;
|
||||
let json = JSON.stringify(object);
|
||||
return core.query(collectionName, json);
|
||||
}
|
||||
return {
|
||||
exist: exist,
|
||||
create: create,
|
||||
insert: insert,
|
||||
remove: remove,
|
||||
query: query
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
database: database,
|
||||
colection: colection
|
||||
};
|
||||
|
24
package.json
Normal file
24
package.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "invodb",
|
||||
"version": "1.0.0",
|
||||
"description": "a nosql json document database",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"install": "node-gyp rebuild"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/YuhangQ/InvoDB.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"gypfile": true,
|
||||
"bugs": {
|
||||
"url": "https://github.com/YuhangQ/InvoDB/issues"
|
||||
},
|
||||
"homepage": "https://github.com/YuhangQ/InvoDB#readme",
|
||||
"dependencies": {
|
||||
"node-addon-api": "^4.2.0"
|
||||
}
|
||||
}
|
@ -5,8 +5,8 @@
|
||||
#ifndef INVODB_BTREE_H
|
||||
#define INVODB_BTREE_H
|
||||
|
||||
#include "btree/node.h"
|
||||
#include "utils/uuid.h"
|
||||
#include "node.h"
|
||||
#include "../utils/uuid.h"
|
||||
|
||||
#define M_SIZE 1000 / (K_SIZE + 4)
|
||||
|
@ -13,8 +13,8 @@
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <type_traits>
|
||||
#include "file/page_manager.h"
|
||||
#include "invodb/utils/cache.h"
|
||||
#include "../file/page_manager.h"
|
||||
#include "../utils/cache.h"
|
||||
|
||||
template<int M_SIZE, typename KT, int K_SIZE>
|
||||
class BTreeNode {
|
@ -27,6 +27,10 @@ Collection& Collection::createCollection(const std::string &name) {
|
||||
return *col;
|
||||
}
|
||||
|
||||
bool Collection::existsCollection(const std::string& name) {
|
||||
return map.count(name) != 0;
|
||||
}
|
||||
|
||||
Collection &Collection::getCollection(const std::string &name) {
|
||||
if(map.count(name) == 0) {
|
||||
throw "no such collection";
|
||||
@ -55,7 +59,7 @@ void Collection::insert(nlohmann::json &json) {
|
||||
int add = PageManager::Instance().saveJSONToFile(json);
|
||||
uuid->insert(id, add);
|
||||
|
||||
//Logger::info<std::string, std::string>("INSERT ", json.dump());
|
||||
Logger::info<std::string, std::string>("INSERT ", json.dump());
|
||||
|
||||
// add index
|
||||
indexJSON("", json, add);
|
@ -5,16 +5,16 @@
|
||||
#ifndef INVODB_COLLECTION_H
|
||||
#define INVODB_COLLECTION_H
|
||||
|
||||
#include "file/page_manager.h"
|
||||
#include "utils/logger.h"
|
||||
#include "btree/btree.h"
|
||||
#include "json/json.hpp"
|
||||
#include "../file/page_manager.h"
|
||||
#include "../utils/logger.h"
|
||||
#include "../btree/btree.h"
|
||||
#include "../json/json.hpp"
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include "utils/uuid.h"
|
||||
#include "btree/list.h"
|
||||
#include "../utils/uuid.h"
|
||||
#include "../btree/list.h"
|
||||
|
||||
class Collection {
|
||||
public:
|
||||
@ -23,6 +23,7 @@ public:
|
||||
std::vector<nlohmann::json> query(const nlohmann::json &json);
|
||||
static void loadCollections();
|
||||
static Collection& getCollection(const std::string& name);
|
||||
static bool existsCollection(const std::string& name);
|
||||
static Collection& createCollection(const std::string& name);
|
||||
|
||||
void test();
|
@ -152,11 +152,11 @@ std::set<nlohmann::json> Collection::innerQuery(const std::string &prefix, const
|
||||
|
||||
auto str = json.dump();
|
||||
|
||||
printf("query: %s prefix: %s\n", str.c_str(), prefix.c_str());
|
||||
printf("result: \n");
|
||||
for(auto it=res.begin(); it!=res.end(); it++) {
|
||||
printf(" - %s\n", it->dump().c_str());
|
||||
}
|
||||
// printf("query: %s prefix: %s\n", str.c_str(), prefix.c_str());
|
||||
// printf("result: \n");
|
||||
// for(auto it=res.begin(); it!=res.end(); it++) {
|
||||
// printf(" - %s\n", it->dump().c_str());
|
||||
// }
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -267,7 +267,7 @@ std::set<nlohmann::json>
|
||||
Collection::queryNumber(const std::string &prefix, const double &minValue, const double &maxValue, const int &mod) {
|
||||
std::set<nlohmann::json> res;
|
||||
auto treeName = prefix + "$number";
|
||||
printf(">>>> %s %f %f\n", prefix.c_str(), minValue, maxValue);
|
||||
//printf(">>>> %s %f %f\n", prefix.c_str(), minValue, maxValue);
|
||||
|
||||
if(!index->exists(treeName)) {
|
||||
return res;
|
@ -3,10 +3,10 @@
|
||||
//
|
||||
|
||||
#include "page_manager.h"
|
||||
#include "btree/list.h"
|
||||
|
||||
|
||||
int PageManager::loadDatabase(const char *filename) {
|
||||
int PageManager::loadDatabase(const char *filename) {
|
||||
std::ofstream file(filename, std::fstream::out);
|
||||
file.close();
|
||||
Instance().stream.open(filename);
|
||||
Instance().stream.seekp(0, std::ios::end);
|
||||
int index = Instance().stream.tellp() / 1024;
|
@ -9,12 +9,9 @@
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
|
||||
#include "../json/json.hpp"
|
||||
#include "../utils/cache.h"
|
||||
#include "storage_page.h"
|
||||
#include "json/json.hpp"
|
||||
#include "invodb/utils/cache.h"
|
||||
|
||||
template<typename T, int T_SIZE>
|
||||
class List;
|
||||
|
||||
class PageManager {
|
||||
public:
|
@ -62,6 +62,8 @@ int StoragePage::getAddress() {
|
||||
}
|
||||
|
||||
StoragePage::StoragePage() {
|
||||
|
||||
printf("aha!\n");
|
||||
memset(page, 0, sizeof(page));
|
||||
}
|
||||
|
69
src/main.cpp
Normal file
69
src/main.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
//
|
||||
// Created by YuhangQ on 2021/9/24.
|
||||
//
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#include <napi.h>
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
|
||||
void database(const CallbackInfo& info) {
|
||||
std::string filename = info[0].As<String>();
|
||||
PageManager::loadDatabase(filename.c_str());
|
||||
Collection::loadCollections();
|
||||
}
|
||||
|
||||
Boolean exists(const CallbackInfo& info) {
|
||||
std::string colName = info[0].As<String>();
|
||||
return Boolean::New(info.Env(), Collection::existsCollection(colName));
|
||||
}
|
||||
|
||||
void create(const CallbackInfo& info) {
|
||||
std::string colName = info[0].As<String>();
|
||||
Collection::createCollection(colName);
|
||||
}
|
||||
|
||||
void insert(const CallbackInfo& info) {
|
||||
std::string colName = info[0].As<String>();
|
||||
std::string json = info[1].As<String>();
|
||||
|
||||
auto j = nlohmann::json::parse(json);
|
||||
Collection::getCollection(colName).insert(j);
|
||||
}
|
||||
|
||||
Array query(const CallbackInfo& info) {
|
||||
std::string colName = info[0].As<String>();
|
||||
std::string json = info[1].As<String>();
|
||||
|
||||
auto j = nlohmann::json::parse(json);
|
||||
auto result = Collection::getCollection(colName).query(j);
|
||||
|
||||
auto res = Array::New(info.Env(), result.size());
|
||||
for(int i=0; i<result.size(); i++) {
|
||||
res.Set(i, String::New(info.Env(), result[i].dump()));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void _remove(const CallbackInfo& info) {
|
||||
std::string colName = info[0].As<String>();
|
||||
std::string json = info[1].As<String>();
|
||||
|
||||
auto j = nlohmann::json::parse(json);
|
||||
Collection::getCollection(colName).remove(j);
|
||||
}
|
||||
|
||||
Object Init(Env env, Object exports) {
|
||||
srand(time(0));
|
||||
exports.Set("database", Function::New(env, database));
|
||||
exports.Set("exists", Function::New(env, exists));
|
||||
exports.Set("create", Function::New(env, create));
|
||||
exports.Set("insert", Function::New(env, insert));
|
||||
exports.Set("query", Function::New(env, query));
|
||||
exports.Set("remove", Function::New(env, _remove));
|
||||
return exports;
|
||||
}
|
||||
NODE_API_MODULE(core, Init)
|
@ -1,11 +1,9 @@
|
||||
//
|
||||
// Created by YuhangQ on 2021/9/24.
|
||||
//
|
||||
|
||||
#include "main.h"
|
||||
|
||||
|
||||
void testAndBenchmark(int n);
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <vector>
|
||||
#include "../collection/collection.h"
|
||||
#include "../btree/list.h"
|
||||
|
||||
Collection *col;
|
||||
|
||||
@ -53,84 +51,6 @@ void terminal() {
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int t = time(0);
|
||||
srand(1635418590);
|
||||
//srand(t);
|
||||
printf("seed: %d\n", t);
|
||||
|
||||
system("rm -rf test.invodb && touch test.invodb");
|
||||
|
||||
PageManager::loadDatabase("test.invodb");
|
||||
|
||||
Collection::loadCollections();
|
||||
|
||||
PageManager& manager = PageManager::Instance();
|
||||
|
||||
try {
|
||||
col = &Collection::getCollection("hello");
|
||||
} catch(const char *error) {
|
||||
Collection::createCollection("hello");
|
||||
col = &Collection::getCollection("hello");
|
||||
}
|
||||
|
||||
// nlohmann::json j = nlohmann::json::parse(R"(
|
||||
//{
|
||||
// "title" : "MongoDB 教程",
|
||||
// "description" : "MongoDB 是一个 Nosql 数据库",
|
||||
// "by" : "菜鸟教程",
|
||||
// "url" : "http://www.runoob.com",
|
||||
// "tags" : [
|
||||
// "mongodb",
|
||||
// "database",
|
||||
// "NoSQL"
|
||||
// ],
|
||||
// "likes" : 100
|
||||
//}
|
||||
// )");
|
||||
//
|
||||
// col->insert(j);
|
||||
//
|
||||
// col->query(nlohmann::json::parse(R"(
|
||||
//{
|
||||
// "likes": {"$gt":50},
|
||||
// "$or": [
|
||||
// {"by": "菜鸟教程"},
|
||||
// {"title": "MongoDB 教程"}
|
||||
// ]
|
||||
//}
|
||||
// )"));
|
||||
|
||||
terminal();
|
||||
|
||||
|
||||
// freopen("qq.txt", "r", stdin);
|
||||
// const int n = 1000000;
|
||||
// char qq[100], phone[100];
|
||||
//
|
||||
// clock_t start = clock();
|
||||
// for(int i=0; i<n; i++) {
|
||||
// scanf("%s%s", qq, phone);
|
||||
// nlohmann::json json;
|
||||
// json["qq"] = qq;
|
||||
// json["phone"] = phone;
|
||||
// col->insert(json);
|
||||
//
|
||||
// if(i % (n/1000) == 0) {
|
||||
// printf("[%d/%d] time=%fs!\n", i, n, (double)(clock() - start) / CLOCKS_PER_SEC);
|
||||
// start = clock();
|
||||
// }
|
||||
// }
|
||||
|
||||
//col->test();
|
||||
|
||||
|
||||
|
||||
|
||||
//testAndBenchmark(20000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void testAndBenchmark(int n) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include "invodb/file/storage_page.h"
|
||||
#include "../file/storage_page.h"
|
||||
|
||||
template<typename KT, typename VT>
|
||||
class LRUCache {
|
Loading…
x
Reference in New Issue
Block a user