6 Star 4 Fork 2

GPLme / SG-Database

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
IO.hpp 10.30 KB
一键复制 编辑 原始数据 按行查看 历史
ECIR 提交于 2021-04-07 15:50 . 存储时将,转义
#pragma once
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <iostream>
#include "col.hpp"
#include "index.hpp"
#include <QMutex>
using namespace std;
class IO
{
public:
static QMutex mutex;
static string default_path;
static int singleFileLen;
static map<string,int> tablesBlockNum;
static bool if_file_exist(const string& path)
{
ifstream f(path);
return f.good();
}
static int table_blocks_num(const string& path,int start=1){
int num=start-1;
while (IO::if_file_exist(IO::path_to_splitpath(path,num+1))) {
++num;
}
return num;
}
static void del_table_blocks(const string& ID,const int& start=1){
const string& path=IO::ID_to_path(ID);
int num;
if(IO::tablesBlockNum.find(ID)==IO::tablesBlockNum.end()){
num=table_blocks_num(path,start);
}
else{
num=IO::tablesBlockNum[ID];
}
for(int i=start;i<=num;++i){
const string& splitPath=IO::path_to_splitpath(path,i);
remove(splitPath.c_str());
remove(IO::path_to_lenpath(splitPath).c_str());
}
}
static string ID_to_path(const string& ID){
return default_path+"\\"+ID+".csv";
}
static string path_to_lenpath(const string& path)
{
string len_path=path;
len_path.insert(len_path.find_last_of("."),"_len");
return len_path;
}
static string path_to_splitpath(const string& path,const int& num){
string split_path=path;
split_path.insert(split_path.find_last_of("."),"_part"+to_string(num));
return split_path;
}
static string read_single_diskblock(const string& path){
const string& to_do=IO::read_from_file(path);
if(!IO::if_file_exist(IO::path_to_lenpath(path))){
const vector<vector<int>>& len_data=IO::strdata_to_lendata(to_do);
IO::write_to_len_file(path,len_data);
}
return to_do;
}
static int put_single_block_data(vector<col*>& cols,const string& to_do){
long long beg = 0;
int rowCount=-1;
for(long long i=0;i<to_do.size();++i){
char tmp=to_do[i];
if (tmp == '\n') {
const string& row = to_do.substr(beg, i - beg)+',';
beg = i + 1;
if(row[0]=='#'||rowCount==-1){
if(rowCount==-1){
++rowCount;
}
continue;
}
int row_beg = 0;
int tmpColNum=0;
for (int j = 1; j < row.length(); j++) {
if (row[j] == ','&&row[j-1]!='/') {
string item = row.substr(row_beg, j - row_beg);
#ifdef CommaReplace
item=helper::reEscape(item);
#endif
col* tmpCol=cols[tmpColNum];
TYPE tmpType=tmpCol->getType();
tmpCol->add(typeHelper::typehelper->strToBasic(item,tmpType));
row_beg = j + 1;
++tmpColNum;
}
}
++rowCount;
}
}
return rowCount;
}
static string read_from_file(const string& path)
{
fstream process(path, ios::in);
if (!process.is_open())
throw string("fail to open the file(read)");
stringstream buffer;
buffer << process.rdbuf();
string to_do = buffer.str();
process.close();
return to_do;
}
static void write_to_file(const string& path,const string& data)
{
fstream write(path,ios::out|ios::trunc);
if (!write.is_open())
throw string("fail to open the file(write)");
write.seekp(0, ios::beg);
write << data;
write.flush();
}
static vector<vector<int>> read_from_len_file(const string& path)
{
string ts=path_to_lenpath(path);
fstream process(path_to_lenpath(path), ios::in);
if (!process.is_open())
throw string("fail to open the file(read)");
stringstream buffer;
buffer << process.rdbuf();
string len_data = buffer.str();
process.close();
vector<vector<int>> len_vec;
int beg = 0;
for (int i = 0; i < len_data.length(); i++) {
if (len_data[i] == '\n') {
string row = len_data.substr(beg, i - beg);
row = row + ",";
vector<int> row_vec;
int row_beg = 0;
for (int j = 0; j < row.length(); j++) {
if (row[j] == ',') {
string item = row.substr(row_beg, j - row_beg);
row_vec.push_back(stoi(item));
row_beg = j + 1;
}
}
len_vec.push_back(row_vec);
beg = i + 1;
}
}
return len_vec;
}
static void write_to_len_file(const string& path,const vector<vector<int>>& len_data)
{
string len_string="";
for(int i=0;i<len_data.size();i++){
len_string=len_string+to_string(len_data[i][0])+","+to_string(len_data[i][1])+"\n";
}
fstream write(path_to_lenpath(path),ios::out|ios::trunc);
if (!write.is_open())
throw string("fail to open the file(write)");
write.seekp(0, ios::beg);
write << len_string;
write.flush();
}
static vector<vector<int>> strdata_to_lendata(const string& to_do){
vector<vector<int>> len_data;
int beg_get_len=0;
int row_get_len=0;
for(int i=0;i<to_do.length();i++){
if(to_do[i]=='\n'){
len_data.push_back(vector<int>(2,0));
len_data[row_get_len][0]=(i-beg_get_len+1);
beg_get_len=i+1;
row_get_len++;
}
}
return len_data;
}
static tuple<vector<col*>,vector<IndexType>> get_empty_table_cols(const string& tmpData){
vector<col*> cols;
vector<IndexType> indTypes;
string ID;
TYPE type;
IndexType indexType;
long long start=0;
int colonNum=0;
for(long long i=0;i<tmpData.size();++i){
char tmpChar=tmpData[i];
if(tmpChar==':'){
if(colonNum==0)
ID=tmpData.substr(start,i-start);
else
type=TYPE(stoi(tmpData.substr(start,i-start)));
start=i+1;
colonNum++;
}
else if(tmpChar==','||tmpChar=='\n'){
indexType=IndexType(stoi(tmpData.substr(start,i-start)));
indTypes.push_back(indexType);
cols.push_back(new col(type, ID));
if(tmpChar=='\n'){
break;
}
start=i+1;
colonNum=0;
}
}
return make_tuple(cols,indTypes);
}
static void do_add(const string& new_data,vector<vector<int>>& len_data,fstream& write)
{
write.seekp(0,ios::end);
write << new_data;
vector<int> item;
item.push_back(new_data.length());
item.push_back(len_data[len_data.size()-1][1]);
len_data.push_back(item);
}
static void Add(vector<Basic*> turple,map<int,fstream>& fileStore,map<int,vector<vector<int>>>& lenStore,const string& ID,vector<int>& blocksLen){
const string& path=IO::ID_to_path(ID);
string new_data="";
for (int i=0;i<turple.size();i++){
string tmpData=turple[i]->toStr();
#ifdef CommaReplace
tmpData=helper::toEscapeStr(tmpData);
#endif
if(i!=turple.size()-1){
new_data.append(tmpData+",");
}
else{
new_data.append(tmpData+"\n");
}
}
const string& splitPath=IO::path_to_splitpath(path,blocksLen.size());
if(lenStore.find(blocksLen.size())==lenStore.end()){
lenStore[blocksLen.size()]=IO::read_from_len_file(splitPath);
}
vector<vector<int>> lenData= lenStore[blocksLen.size()];
if(lenData.size()>IO::singleFileLen){
const string& data=IO::read_from_file(splitPath);
const string& title=data.substr(0,data.find_first_of('\n')+1);
const string& result=title+new_data;
const string& tmp=IO::path_to_splitpath(path,blocksLen.size()+1);
const vector<vector<int>>& len_data=IO::strdata_to_lendata(result);
IO::write_to_file(tmp,result);
IO::write_to_len_file(tmp,len_data);
blocksLen.push_back(1);
++IO::tablesBlockNum[ID];
}
else{
if(fileStore.find(blocksLen.size())==fileStore.end()){
fileStore[blocksLen.size()]=fstream(splitPath);
}
IO::do_add(new_data,lenStore[blocksLen.size()],fileStore[blocksLen.size()]);
blocksLen[blocksLen.size()-1]=blocksLen[blocksLen.size()-1]+1;
}
}
static void do_del(int opSub,vector<vector<int>>& len_data,fstream& write)
{
int opRow=opSub+len_data[opSub+1][1]+1;
long long loc=0;
for(int i=0;i<opRow;i++){
loc+=len_data[i][0];
}
write.seekp(loc+opRow,ios::beg);
write << "#";
for(int i=opSub+1;i<len_data.size();i++){
len_data[i][1]=len_data[i][1]+1;
}
}
static void Del(int opSub,map<int,fstream>& fileStore,map<int,vector<vector<int>>>& lenStore,const string& ID,vector<int>& blocksLen){
const string& path=IO::ID_to_path(ID);
int num=1;
for(const int& len:blocksLen){
if(opSub-len>=0){
opSub=opSub-len;
++num;
}
else{
break;
}
}
const string& splitPath=IO::path_to_splitpath(path,num);
if(lenStore.find(num)==lenStore.end()){
lenStore[num]=IO::read_from_len_file(splitPath);
}
if(fileStore.find(num)==fileStore.end()){
fileStore[num]=fstream(splitPath);
}
IO::do_del(opSub,lenStore[num],fileStore[num]);
blocksLen[num-1]=blocksLen[num-1]-1;
}
};
C++
1
https://gitee.com/sg-first/SG-Database.git
git@gitee.com:sg-first/SG-Database.git
sg-first
SG-Database
SG-Database
master

搜索帮助