mirror of
https://github.com/YuhangQ/InvoDB.git
synced 2025-01-26 06:30:57 +00:00
完善数据库查询算法
This commit is contained in:
parent
99265240b8
commit
6c538caaab
@ -11,4 +11,4 @@ include_directories(./invodb)
|
||||
|
||||
add_executable(InvoDB
|
||||
invodb/main.cpp
|
||||
invodb/main.h invodb/file/page_manager.cpp invodb/file/page_manager.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 invodb/btree/node.h invodb/btree/btree.h invodb/index/index.cpp invodb/index/index.h invodb/btree/list.h invodb/index/query.cpp invodb/index/query.h invodb/models/cache.h)
|
||||
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)
|
||||
|
@ -8,14 +8,18 @@
|
||||
#include "btree/node.h"
|
||||
#include "utils/uuid.h"
|
||||
|
||||
#define M_SIZE 1000 / (K_SIZE + 4)
|
||||
|
||||
template<typename KT, int K_SIZE>
|
||||
class BTree {
|
||||
public:
|
||||
|
||||
static std::shared_ptr<BTreeNode<M_SIZE, KT, K_SIZE>> getNode(const int &index);
|
||||
|
||||
BTree(const int& address);
|
||||
void insert(const KT &key, const int &value);
|
||||
void update(const KT &key, const int &value);
|
||||
void remove(const KT &key);
|
||||
|
||||
bool exists(const KT &key);
|
||||
int getNodeSize();
|
||||
int find(const KT &key);
|
||||
@ -37,9 +41,15 @@ private:
|
||||
void insertInternal(const KT &key, int curAdd, int lLeafAdd, int rLeafAdd);
|
||||
int root;
|
||||
int n_size;
|
||||
static const int M_SIZE = 1000 / (K_SIZE + 4);
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<typename KT, int K_SIZE>
|
||||
std::shared_ptr<BTreeNode<M_SIZE, KT, K_SIZE>> BTree<KT, K_SIZE>::getNode(const int &index) {
|
||||
return BTreeNode<M_SIZE, KT, K_SIZE>::getNode(index);
|
||||
}
|
||||
|
||||
template<typename KT, int K_SIZE>
|
||||
BTree<KT, K_SIZE>::BTree(const int& address) {
|
||||
root = address;
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <map>
|
||||
#include <type_traits>
|
||||
#include "file/page_manager.h"
|
||||
#include "invodb/models/cache.h"
|
||||
#include "invodb/utils/cache.h"
|
||||
|
||||
template<int M_SIZE, typename KT, int K_SIZE>
|
||||
class BTreeNode {
|
||||
@ -37,6 +37,7 @@ public:
|
||||
int save();
|
||||
bool enough();
|
||||
bool full();
|
||||
void print();
|
||||
|
||||
KT keySet[m + 1];
|
||||
int linkSet[m + 1];
|
||||
@ -232,4 +233,19 @@ bool BTreeNode<M_SIZE, KT, K_SIZE>::full() {
|
||||
return size == maxCount;
|
||||
}
|
||||
|
||||
template<int M_SIZE, typename KT, int K_SIZE>
|
||||
void BTreeNode<M_SIZE, KT, K_SIZE>::print() {
|
||||
|
||||
printf("----Node: %d-----\n", address);
|
||||
|
||||
for(int i=0; i<size; i++) {
|
||||
std::cout << keySet[i] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
for(int i=0; i<=size-leaf; i++) {
|
||||
printf("%d ", linkSet[i]);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
#endif //INVODB_NODE_H
|
||||
|
94
invodb/collection/collection.cpp
Normal file
94
invodb/collection/collection.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
//
|
||||
// Created by YuhangQ on 2021/10/9.
|
||||
//
|
||||
|
||||
#include "collection.h"
|
||||
|
||||
BTree<std::string, 32> Collection::colList(1);
|
||||
std::map<std::string, Collection*> Collection::map;
|
||||
|
||||
void Collection::loadCollections() {
|
||||
int cnt = 0;
|
||||
for(auto& key : colList.keySet()) {
|
||||
map.insert(std::make_pair(key, new Collection(key, colList.find(key))));
|
||||
cnt++;
|
||||
}
|
||||
Logger::info<std::string, int>("Successfully load Collections: ", cnt);
|
||||
}
|
||||
|
||||
Collection& Collection::createCollection(const std::string &name) {
|
||||
// exist
|
||||
if(map.count(name) != 0) {
|
||||
return *map[name];
|
||||
}
|
||||
colList.insert(name, PageManager::Instance().allocate());
|
||||
Collection *col = new Collection(name, colList.find(name));
|
||||
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];
|
||||
}
|
||||
|
||||
Collection::Collection(const std::string &name, const int &firstPage) {
|
||||
Logger::info<std::string, std::string>("load Collection: ", name);
|
||||
index = new BTree<std::string, 128>(firstPage);
|
||||
if(!index->exists("__INVO_ID__")) {
|
||||
index->insert("__INVO_ID__", PageManager::Instance().allocate());
|
||||
}
|
||||
uuid = new BTree<std::string, 32>(index->find("__INVO_ID__"));
|
||||
}
|
||||
|
||||
void Collection::insert(nlohmann::json &json) {
|
||||
|
||||
if(json["__INVO_ID__"].empty()) {
|
||||
json["__INVO_ID__"] = generateUUID();
|
||||
} else {
|
||||
remove(json);
|
||||
}
|
||||
|
||||
std::string id = json["__INVO_ID__"].get<std::string>();
|
||||
int add = PageManager::Instance().saveJSONToFile(json);
|
||||
uuid->insert(id, add);
|
||||
|
||||
//Logger::info<std::string, std::string>("INSERT ", json.dump());
|
||||
|
||||
// add index
|
||||
indexJSON("", json, add);
|
||||
}
|
||||
|
||||
void Collection::remove(const nlohmann::json &json) {
|
||||
if(json["__INVO_ID__"].empty()) {
|
||||
throw "no invo_id";
|
||||
}
|
||||
std::string id = json["__INVO_ID__"].get<std::string>();
|
||||
|
||||
|
||||
int address = uuid->find(id);
|
||||
uuid->remove(id);
|
||||
|
||||
nlohmann::json jsonInDisk = PageManager::Instance().readJSONFromFile(address);
|
||||
|
||||
clearIndex("", json, address);
|
||||
|
||||
PageManager::Instance().release(address);
|
||||
}
|
||||
|
||||
|
||||
void Collection::test() {
|
||||
index->print();
|
||||
auto qq = new BTree<std::string, 128>(7);
|
||||
while(true) {
|
||||
std::string q;
|
||||
std::cin >> q;
|
||||
List<int, 4> list(qq->find(q));
|
||||
//list.print();
|
||||
for(auto& add : list.all()) {
|
||||
std::cout << ">> " << PageManager::Instance().readJSONFromFile(add).dump() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ class Collection {
|
||||
public:
|
||||
void insert(nlohmann::json &json);
|
||||
void remove(const nlohmann::json &json);
|
||||
|
||||
std::vector<nlohmann::json> query(const nlohmann::json &json);
|
||||
static void loadCollections();
|
||||
static Collection& getCollection(const std::string& name);
|
||||
static Collection& createCollection(const std::string& name);
|
||||
@ -28,7 +28,6 @@ public:
|
||||
void test();
|
||||
|
||||
private:
|
||||
|
||||
void indexJSON(const std::string prefix, const nlohmann::json &json, const int& address);
|
||||
void insertIndex(const std::string indexName, const std::string indexValue, const int& address);
|
||||
void insertIndex(const std::string indexName, double indexValue, const int& address);
|
||||
@ -38,6 +37,15 @@ private:
|
||||
void removeIndex(const std::string indexName, double indexValue, const int& address);
|
||||
void removeIndex(const std::string indexName, bool indexValue, const int& address);
|
||||
|
||||
std::set<nlohmann::json> setIntersection(const std::set<nlohmann::json> &a, const std::set<nlohmann::json> &b);
|
||||
std::set<nlohmann::json> setUnion(const std::set<nlohmann::json> &a, const std::set<nlohmann::json> &b);
|
||||
|
||||
std::set<nlohmann::json> innerQuery(const std::string &prefix, const nlohmann::json &json);
|
||||
std::set<nlohmann::json> queryString(const std::string &prefix, const std::string &minValue, const std::string &maxValue, const int &mod = 0);
|
||||
std::set<nlohmann::json> queryNumber(const std::string &prefix, const double &minValue, const double &maxValue, const int &mod = 0);
|
||||
std::set<nlohmann::json> queryBool(const std::string &prefix, const bool &value);
|
||||
std::set<nlohmann::json> queryRange(const std::string &prefix, const nlohmann::json &json);
|
||||
|
||||
static std::map<std::string, Collection*> map;
|
||||
static BTree<std::string, 32> colList;
|
||||
|
@ -1,83 +1,9 @@
|
||||
//
|
||||
// Created by YuhangQ on 2021/10/9.
|
||||
// Created by YuhangQ on 2021/11/7.
|
||||
//
|
||||
|
||||
#include "collection.h"
|
||||
|
||||
BTree<std::string, 32> Collection::colList(1);
|
||||
std::map<std::string, Collection*> Collection::map;
|
||||
|
||||
void Collection::loadCollections() {
|
||||
int cnt = 0;
|
||||
for(auto& key : colList.keySet()) {
|
||||
map.insert(std::make_pair(key, new Collection(key, colList.find(key))));
|
||||
cnt++;
|
||||
}
|
||||
Logger::info<std::string, int>("Successfully load Collections: ", cnt);
|
||||
}
|
||||
|
||||
Collection& Collection::createCollection(const std::string &name) {
|
||||
// exist
|
||||
if(map.count(name) != 0) {
|
||||
return *map[name];
|
||||
}
|
||||
colList.insert(name, PageManager::Instance().allocate());
|
||||
Collection *col = new Collection(name, colList.find(name));
|
||||
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];
|
||||
}
|
||||
|
||||
Collection::Collection(const std::string &name, const int &firstPage) {
|
||||
Logger::info<std::string, std::string>("load Collection: ", name);
|
||||
index = new BTree<std::string, 128>(firstPage);
|
||||
if(!index->exists("__INVO_ID__")) {
|
||||
index->insert("__INVO_ID__", PageManager::Instance().allocate());
|
||||
}
|
||||
uuid = new BTree<std::string, 32>(index->find("__INVO_ID__"));
|
||||
}
|
||||
|
||||
void Collection::insert(nlohmann::json &json) {
|
||||
|
||||
if(json["__INVO_ID__"].empty()) {
|
||||
json["__INVO_ID__"] = generateUUID();
|
||||
} else {
|
||||
remove(json);
|
||||
}
|
||||
|
||||
std::string id = json["__INVO_ID__"].get<std::string>();
|
||||
int add = PageManager::Instance().saveJSONToFile(json);
|
||||
uuid->insert(id, add);
|
||||
|
||||
//Logger::info<std::string, std::string>("INSERT ", json.dump());
|
||||
|
||||
// add index
|
||||
indexJSON("", json, add);
|
||||
}
|
||||
|
||||
void Collection::remove(const nlohmann::json &json) {
|
||||
if(json["__INVO_ID__"].empty()) {
|
||||
throw "no invo_id";
|
||||
}
|
||||
std::string id = json["__INVO_ID__"].get<std::string>();
|
||||
|
||||
|
||||
int address = uuid->find(id);
|
||||
uuid->remove(id);
|
||||
|
||||
nlohmann::json jsonInDisk = PageManager::Instance().readJSONFromFile(address);
|
||||
|
||||
clearIndex("", json, address);
|
||||
|
||||
PageManager::Instance().release(address);
|
||||
}
|
||||
|
||||
// age=1 age=“hello”
|
||||
void Collection::indexJSON(const std::string prefix, const nlohmann::json &json, const int& address) {
|
||||
// even easier with structured bindings (C++17)
|
||||
@ -88,7 +14,7 @@ void Collection::indexJSON(const std::string prefix, const nlohmann::json &json,
|
||||
if(value.is_boolean()) insertIndex(prefix + key, value.get<bool>(), address);
|
||||
if(value.is_number()) insertIndex(prefix + key, value.get<double>(), address);
|
||||
if(value.is_string()) insertIndex(prefix + key, value.get<std::string>(), address);
|
||||
//if(value.is_object()) indexJSON(prefix + key + ".", value.get<nlohmann::json>(),address);
|
||||
if(value.is_object()) indexJSON(prefix + key + ".", value.get<nlohmann::json>(),address);
|
||||
if(value.is_array()) {
|
||||
for(auto& element : value.get<nlohmann::json>()) {
|
||||
if(element.is_string()) insertIndex(prefix + key, element.get<std::string>(), address);
|
||||
@ -110,7 +36,7 @@ void Collection::insertIndex(const std::string indexName, const std::string inde
|
||||
index->insert(treeName, PageManager::Instance().allocate());
|
||||
}
|
||||
|
||||
BTree<std::string, 128> indexTree(index->find(treeName));
|
||||
BTree<std::string, 64> indexTree(index->find(treeName));
|
||||
|
||||
if(!indexTree.exists(indexValue)) {
|
||||
indexTree.insert(indexValue, PageManager::Instance().allocate());
|
||||
@ -227,18 +153,4 @@ void Collection::removeIndex(const std::string indexName, bool indexValue, const
|
||||
|
||||
List<int, 4> list(indexTree.find(indexValue));
|
||||
list.remove(address);
|
||||
}
|
||||
|
||||
void Collection::test() {
|
||||
index->print();
|
||||
auto qq = new BTree<std::string, 128>(7);
|
||||
while(true) {
|
||||
std::string q;
|
||||
std::cin >> q;
|
||||
List<int, 4> list(qq->find(q));
|
||||
//list.print();
|
||||
for(auto& add : list.all()) {
|
||||
std::cout << ">> " << PageManager::Instance().readJSONFromFile(add).dump() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
371
invodb/collection/query.cpp
Normal file
371
invodb/collection/query.cpp
Normal file
@ -0,0 +1,371 @@
|
||||
//
|
||||
// Created by projector-user on 11/1/21.
|
||||
//
|
||||
|
||||
#include "collection.h"
|
||||
|
||||
std::vector<nlohmann::json> Collection::query(const nlohmann::json &json) {
|
||||
std::vector<nlohmann::json> res;
|
||||
|
||||
innerQuery("", json);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* range search mod explain
|
||||
* mod = 0: minValue <= value <= maxValue
|
||||
* mod = 1: minValue < value <= maxValue
|
||||
* mod = 2: minValue <= value < maxValue
|
||||
* mod = 3: minValue < value < maxValue
|
||||
* mod = 4: value < maxValue
|
||||
* mod = 5: value <= maxValue
|
||||
* mod = 6: value > minValue
|
||||
* mod = 7: value >= minValue
|
||||
*/
|
||||
|
||||
std::set<nlohmann::json> Collection::queryRange(const std::string &prefix, const nlohmann::json &json) {
|
||||
|
||||
printf(">> queryRange prefix: %s query: %s\n", prefix.c_str(), json.dump().c_str());
|
||||
|
||||
std::set<nlohmann::json> set;
|
||||
|
||||
for(auto& [key, value] : json.items()) {
|
||||
if(value.is_number()) {
|
||||
|
||||
if(json.contains("$ne")) {
|
||||
if(!index->exists(prefix+"$number")) {
|
||||
return set;
|
||||
}
|
||||
BTree<double, 8> tree(index->find(prefix+"$number"));
|
||||
for(auto& key: tree.keySet()) {
|
||||
if(key != json["$ne"].get<double>()) continue;
|
||||
List<int, 4> list(tree.find(key));
|
||||
for(auto& add : list.all()) {
|
||||
set.insert(PageManager::Instance().readJSONFromFile(add));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(json.contains("$gt")) {
|
||||
if(json.contains("$lt")) {
|
||||
set = queryNumber(prefix, json["$gt"].get<double>(), json["$lt"].get<double>(), 3);
|
||||
} else if(json.contains("$lte")) {
|
||||
set = queryNumber(prefix, json["$gt"].get<double>(), json["$lte"].get<double>(), 1);
|
||||
} else {
|
||||
|
||||
set = queryNumber(prefix, json["$gt"].get<double>(), 0, 6);
|
||||
|
||||
}
|
||||
} else if(json.contains("$gte")) {
|
||||
if(json.contains("$lt")) {
|
||||
set = queryNumber(prefix, json["$gte"].get<double>(), json["$lt"].get<double>(), 2);
|
||||
} else if(json.contains("$lte")) {
|
||||
set = queryNumber(prefix, json["$gte"].get<double>(), json["$lte"].get<double>(), 0);
|
||||
} else {
|
||||
set = queryNumber(prefix, json["$gte"].get<double>(), 0, 7);
|
||||
}
|
||||
} else if(json.contains("$lt")) {
|
||||
set = queryNumber(prefix, 0, json["$lt"].get<double>(), 4);
|
||||
} else if(json.contains("$lte")) {
|
||||
set = queryNumber(prefix, 0, json["$lte"].get<double>(), 5);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
else if(value.is_string()) {
|
||||
|
||||
if(json.contains("$ne")) {
|
||||
if(!index->exists(prefix+"$string")) {
|
||||
return set;
|
||||
}
|
||||
BTree<std::string, 64> tree(index->find(prefix+"$string"));
|
||||
for(auto& key: tree.keySet()) {
|
||||
if(key != json["$ne"].get<std::string>()) continue;
|
||||
List<int, 4> list(tree.find(key));
|
||||
for(auto& add : list.all()) {
|
||||
set.insert(PageManager::Instance().readJSONFromFile(add));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(json.contains("$gt")) {
|
||||
if(json.contains("$lt")) {
|
||||
set = queryString(prefix, json["$gt"].get<std::string>(), json["$lt"].get<std::string>(), 3);
|
||||
} else if(json.contains("$lte")) {
|
||||
set = queryString(prefix, json["$gt"].get<std::string>(), json["$lte"].get<std::string>(), 1);
|
||||
} else {
|
||||
set = queryString(prefix, json["$gt"].get<std::string>(), "", 6);
|
||||
}
|
||||
} else if(json.contains("$gte")) {
|
||||
if(json.contains("$lt")) {
|
||||
set = queryString(prefix, json["$gte"].get<std::string>(), json["$lt"].get<std::string>(), 2);
|
||||
} else if(json.contains("$lte")) {
|
||||
set = queryString(prefix, json["$gte"].get<std::string>(), json["$lte"].get<std::string>(), 0);
|
||||
} else {
|
||||
set = queryString(prefix, json["$gte"].get<std::string>(), "", 7);
|
||||
}
|
||||
} else if(json.contains("$lt")) {
|
||||
set = queryString(prefix, "", json["$lt"].get<std::string>(), 4);
|
||||
} else if(json.contains("$lte")) {
|
||||
set = queryString(prefix, "", json["$lte"].get<std::string>(), 5);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
std::set<nlohmann::json> Collection::innerQuery(const std::string &prefix, const nlohmann::json &json) {
|
||||
|
||||
for(auto& [key, value] : json.items()) {
|
||||
if(key == "$lt" || key == "$lte" || key == "$gt" || key == "$gte" || key == "$ne") {
|
||||
return queryRange(prefix.substr(0, prefix.size()-1), json);
|
||||
}
|
||||
}
|
||||
|
||||
std::set<nlohmann::json> res;
|
||||
bool init = true;
|
||||
|
||||
for(auto& [key, value] : json.items()) {
|
||||
|
||||
std::set<nlohmann::json> tmp;
|
||||
std::string tPrefix = prefix + key;
|
||||
|
||||
if(key == "$or") {
|
||||
nlohmann::json line = json[key].get<nlohmann::json>();
|
||||
for(auto& obj : line) {
|
||||
tmp = setUnion(tmp, innerQuery(prefix, obj.get<nlohmann::json>()));
|
||||
}
|
||||
} else if(json[key].is_object()) {
|
||||
tmp = innerQuery(prefix + key + ".", json[key].get<nlohmann::json>());
|
||||
} else if(json[key].is_array()) {
|
||||
|
||||
} else if(json[key].is_boolean()) {
|
||||
tmp = queryBool(tPrefix, json[key].get<bool>());
|
||||
} else if(json[key].is_string()) {
|
||||
tmp = queryString(tPrefix, json[key].get<std::string>(), json[key].get<std::string>());
|
||||
} else if(json[key].is_number()) {
|
||||
tmp = queryNumber(tPrefix, json[key].get<double>(), json[key].get<double>());
|
||||
}
|
||||
if(init) res = tmp, init = false;
|
||||
else res = setIntersection(res, tmp);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::set<nlohmann::json>
|
||||
Collection::setIntersection(const std::set<nlohmann::json> &a, const std::set<nlohmann::json> &b) {
|
||||
std::set<nlohmann::json> res;
|
||||
std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::inserter(res, res.end()));
|
||||
return res;
|
||||
}
|
||||
|
||||
std::set<nlohmann::json>
|
||||
Collection::setUnion(const std::set<nlohmann::json> &a, const std::set<nlohmann::json> &b) {
|
||||
std::set<nlohmann::json> res;
|
||||
std::set_union(a.begin(), a.end(), b.begin(), b.end(), std::inserter(res, res.end()));
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* range search mod explain
|
||||
* mod = 0: minValue <= value <= maxValue
|
||||
* mod = 1: minValue < value <= maxValue
|
||||
* mod = 2: minValue <= value < maxValue
|
||||
* mod = 3: minValue < value < maxValue
|
||||
*/
|
||||
|
||||
std::set<nlohmann::json>
|
||||
Collection::queryString(const std::string &prefix, const std::string &minValue, const std::string &maxValue, const int &mod) {
|
||||
std::set<nlohmann::json> res;
|
||||
auto treeName = prefix + "$string";
|
||||
//printf(">>>> %s %s %s\n", prefix.c_str(), minValue.c_str(), maxValue.c_str());
|
||||
if(!index->exists(treeName)) {
|
||||
return res;
|
||||
}
|
||||
BTree<std::string, 64> tree(index->find(treeName));
|
||||
const int K_SIZE = 64;
|
||||
std::shared_ptr<BTreeNode<M_SIZE, std::string , K_SIZE>> node;
|
||||
|
||||
if(mod == 4 || mod == 5) {
|
||||
node = tree.getNode(tree.findNode(maxValue));
|
||||
} else {
|
||||
node = tree.getNode(tree.findNode(minValue));
|
||||
}
|
||||
|
||||
while(true) {
|
||||
bool flag = true;
|
||||
for(int i=0; i<node->size; i++) {
|
||||
if(mod == 0) {
|
||||
if(node->keySet[i] < minValue) continue;
|
||||
if(node->keySet[i] > maxValue) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if(mod == 1) {
|
||||
if(node->keySet[i] <= minValue) continue;
|
||||
if(node->keySet[i] > maxValue) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if(mod == 2) {
|
||||
if(node->keySet[i] < minValue) continue;
|
||||
if(node->keySet[i] >= maxValue) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if(mod == 3) {
|
||||
if(node->keySet[i] <= minValue) continue;
|
||||
if(node->keySet[i] >= maxValue) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if(mod == 4) {
|
||||
if(node->keySet[i] >= maxValue) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if(mod == 5) {
|
||||
if(node->keySet[i] > maxValue) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if(mod == 6) {
|
||||
if(node->keySet[i] <= minValue) continue;
|
||||
} else if(mod == 7) {
|
||||
if(node->keySet[i] < minValue) continue;
|
||||
}
|
||||
List<int, 4> list(node->linkSet[i]);
|
||||
for(auto& add : list.all()) {
|
||||
res.insert(PageManager::Instance().readJSONFromFile(add));
|
||||
}
|
||||
}
|
||||
if(!flag) break;
|
||||
if(node->right == 0) break;
|
||||
node = tree.getNode(node->right);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* range search mod explain
|
||||
* mod = 0: minValue <= value <= maxValue
|
||||
* mod = 1: minValue < value <= maxValue
|
||||
* mod = 2: minValue <= value < maxValue
|
||||
* mod = 3: minValue < value < maxValue
|
||||
*/
|
||||
|
||||
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);
|
||||
|
||||
if(!index->exists(treeName)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
BTree<double, 8> tree(index->find(treeName));
|
||||
const int K_SIZE = 8;
|
||||
std::shared_ptr<BTreeNode<M_SIZE, double , K_SIZE>> node;
|
||||
|
||||
if(mod == 4 || mod == 5) {
|
||||
node = tree.getNode(tree.findNode(maxValue));
|
||||
} else {
|
||||
node = tree.getNode(tree.findNode(minValue));
|
||||
}
|
||||
|
||||
while(true) {
|
||||
bool flag = true;
|
||||
for(int i=0; i<node->size; i++) {
|
||||
|
||||
if(mod == 0) {
|
||||
if(node->keySet[i] < minValue) continue;
|
||||
if(node->keySet[i] > maxValue) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if(mod == 1) {
|
||||
if(node->keySet[i] <= minValue) continue;
|
||||
if(node->keySet[i] > maxValue) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if(mod == 2) {
|
||||
if(node->keySet[i] < minValue) continue;
|
||||
if(node->keySet[i] >= maxValue) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if(mod == 3) {
|
||||
if(node->keySet[i] <= minValue) continue;
|
||||
if(node->keySet[i] >= maxValue) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if(mod == 4) {
|
||||
if(node->keySet[i] >= maxValue) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if(mod == 5) {
|
||||
if(node->keySet[i] > maxValue) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} else if(mod == 6) {
|
||||
if(node->keySet[i] <= minValue) continue;
|
||||
} else if(mod == 7) {
|
||||
if(node->keySet[i] < minValue) continue;
|
||||
}
|
||||
|
||||
|
||||
List<int, 4> list(node->linkSet[i]);
|
||||
for(auto& add : list.all()) {
|
||||
res.insert(PageManager::Instance().readJSONFromFile(add));
|
||||
}
|
||||
}
|
||||
if(!flag) break;
|
||||
if(node->right == 0) break;
|
||||
node = tree.getNode(node->right);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::set<nlohmann::json>
|
||||
Collection::queryBool(const std::string &prefix, const bool &value) {
|
||||
std::set<nlohmann::json> res;
|
||||
auto treeName = prefix + "$boolean";
|
||||
//printf(">>>> %s %s %s\n", prefix.c_str(), minValue.c_str(), maxValue.c_str());
|
||||
if(!index->exists(treeName)) {
|
||||
return res;
|
||||
}
|
||||
BTree<bool, 1> tree(index->find(treeName));
|
||||
auto node = tree.getNode(tree.findNode(value));
|
||||
while(true) {
|
||||
bool flag = true;
|
||||
for(int i=0; i<node->size; i++) {
|
||||
if(node->keySet[i] < value) continue;
|
||||
if(node->keySet[i] > value) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
List<int, 4> list(node->linkSet[i]);
|
||||
for(auto& add : list.all()) {
|
||||
res.insert(PageManager::Instance().readJSONFromFile(add));
|
||||
}
|
||||
}
|
||||
if(!flag) break;
|
||||
if(node->right == 0) break;
|
||||
node = tree.getNode(node->right);
|
||||
}
|
||||
return res;
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include "storage_page.h"
|
||||
#include "json/json.hpp"
|
||||
#include "invodb/models/cache.h"
|
||||
#include "invodb/utils/cache.h"
|
||||
|
||||
template<typename T, int T_SIZE>
|
||||
class List;
|
||||
|
@ -1,5 +0,0 @@
|
||||
//
|
||||
// Created by YuhangQ on 2021/11/1.
|
||||
//
|
||||
|
||||
#include "index.h"
|
@ -1,25 +0,0 @@
|
||||
//
|
||||
// Created by YuhangQ on 2021/11/1.
|
||||
//
|
||||
|
||||
#ifndef INVODB_INDEX_H
|
||||
#define INVODB_INDEX_H
|
||||
|
||||
#include "btree/btree.h"
|
||||
#include "json/json.hpp"
|
||||
|
||||
class Index {
|
||||
public:
|
||||
void insert(const nlohmann::json& json);
|
||||
private:
|
||||
template<typename T>
|
||||
void insertElement(T const& key, const int& add) {
|
||||
BTree<T, 128> treeString;
|
||||
BTree<T, 1> treeBool;
|
||||
BTree<T, 8> treeDouble;
|
||||
BTree<T, 4> treeInt;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif //INVODB_INDEX_H
|
@ -1,9 +0,0 @@
|
||||
//
|
||||
// Created by projector-user on 11/1/21.
|
||||
//
|
||||
|
||||
#include "query.h"
|
||||
|
||||
std::vector<nlohmann::json> Query::find(const nlohmann::json &json) {
|
||||
return std::vector<nlohmann::json>();
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
//
|
||||
// Created by projector-user on 11/1/21.
|
||||
//
|
||||
|
||||
#ifndef INVODB_QUERY_H
|
||||
#define INVODB_QUERY_H
|
||||
|
||||
#include "json/json.hpp"
|
||||
|
||||
class Query {
|
||||
std::vector<nlohmann::json> find(const nlohmann::json &json);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //INVODB_QUERY_H
|
@ -29,42 +29,58 @@ int main() {
|
||||
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
|
||||
}
|
||||
)");
|
||||
|
||||
freopen("qq.txt", "r", stdin);
|
||||
const int n = 1000000;
|
||||
char qq[100], phone[100];
|
||||
col->insert(j);
|
||||
|
||||
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);
|
||||
col->query(nlohmann::json::parse(R"(
|
||||
{
|
||||
"likes": {"$gt":50},
|
||||
"$or": [
|
||||
{"by": "菜鸟教程"},
|
||||
{"title": "MongoDB 教程"}
|
||||
]
|
||||
}
|
||||
)"));
|
||||
|
||||
if(i % (n/1000) == 0) {
|
||||
printf("[%d/%d] time=%fs!\n", i, n, (double)(clock() - start) / CLOCKS_PER_SEC);
|
||||
start = clock();
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
|
||||
// nlohmann::json j = nlohmann::json::parse(R"(
|
||||
//{
|
||||
// "string": "this is a string!",
|
||||
// "double": 3.1415,
|
||||
// "int": 25565,
|
||||
// "bool": true,
|
||||
// "child": {
|
||||
// "id": 3
|
||||
// },
|
||||
// "array": ["1", "2", "3"]
|
||||
//}
|
||||
// )");
|
||||
|
||||
testAndBenchmark(20000);
|
||||
|
||||
//testAndBenchmark(20000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <vector>
|
||||
#include "models/collection.h"
|
||||
#include "collection/collection.h"
|
||||
#include "btree/list.h"
|
||||
|
||||
|
||||
|
@ -11442,11 +11442,11 @@ namespace detail
|
||||
/*
|
||||
@brief an iterator for primitive JSON types
|
||||
|
||||
This class models an iterator for primitive JSON types (boolean, number,
|
||||
This class collection an iterator for primitive JSON types (boolean, number,
|
||||
string). It's only purpose is to allow the iterator/const_iterator classes
|
||||
to "iterate" over primitive values. Internally, the iterator is modeled by
|
||||
a `difference_type` variable. Value begin_value (`0`) models the begin,
|
||||
end_value (`1`) models past the end.
|
||||
a `difference_type` variable. Value begin_value (`0`) collection the begin,
|
||||
end_value (`1`) collection past the end.
|
||||
*/
|
||||
class primitive_iterator_t
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user