-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRelation.cpp
More file actions
102 lines (97 loc) · 3.1 KB
/
Relation.cpp
File metadata and controls
102 lines (97 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <fcntl.h>
#include <iostream>
#include <fstream>
#include <sys/mman.h>
#include <sys/stat.h>
#include "Relation.hpp"
//---------------------------------------------------------------------------
using namespace std;
//---------------------------------------------------------------------------
void Relation::storeRelation(const string& fileName)
// Stores a relation into a binary file
{
ofstream outFile;
outFile.open(fileName,ios::out|ios::binary);
outFile.write((char*)&size,sizeof(size));
auto numColumns=columns.size();
outFile.write((char*)&numColumns,sizeof(size_t));
for (auto c : columns) {
outFile.write((char*)c,size*sizeof(uint64_t));
}
outFile.close();
}
//---------------------------------------------------------------------------
void Relation::storeRelationCSV(const string& fileName)
// Stores a relation into a file (csv), e.g., for loading/testing it with a DBMS
{
ofstream outFile;
outFile.open(fileName+".tbl",ios::out);
for (uint64_t i=0;i<size;++i) {
for (auto& c : columns) {
outFile << c[i] << '|';
}
outFile << "\n";
}
}
//---------------------------------------------------------------------------
void Relation::dumpSQL(const string& fileName,unsigned relationId)
// Dump SQL: Create and load table (PostgreSQL)
{
ofstream outFile;
outFile.open(fileName+".sql",ios::out);
// Create table statement
outFile << "CREATE TABLE r" << relationId << " (";
for (unsigned cId=0;cId<columns.size();++cId) {
outFile << "c" << cId << " bigint" << (cId<columns.size()-1?",":"");
}
outFile << ");\n";
// Load from csv statement
outFile << "copy r" << relationId << " from 'r" << relationId << ".tbl' delimiter '|';\n";
}
//---------------------------------------------------------------------------
void Relation::loadRelation(const char* fileName)
{
int fd = open(fileName, O_RDONLY);
if (fd==-1) {
cerr << "cannot open " << fileName << endl;
throw;
}
// Obtain file size
struct stat sb;
if (fstat(fd,&sb)==-1)
cerr << "fstat\n";
auto length=sb.st_size;
char* addr=static_cast<char*>(mmap(nullptr,length,PROT_READ,MAP_PRIVATE,fd,0u));
if (addr==MAP_FAILED) {
cerr << "cannot mmap " << fileName << " of length " << length << endl;
throw;
}
if (length<16) {
cerr << "relation file " << fileName << " does not contain a valid header" << endl;
throw;
}
this->size=*reinterpret_cast<uint64_t*>(addr);
addr+=sizeof(size);
auto numColumns=*reinterpret_cast<size_t*>(addr);
addr+=sizeof(size_t);
for (unsigned i=0;i<numColumns;++i) {
this->columns.push_back(reinterpret_cast<uint64_t*>(addr));
addr+=size*sizeof(uint64_t);
}
}
//---------------------------------------------------------------------------
Relation::Relation(const char* fileName) : ownsMemory(false)
// Constructor that loads relation from disk
{
loadRelation(fileName);
}
//---------------------------------------------------------------------------
Relation::~Relation()
// Destructor
{
if (ownsMemory) {
for (auto c : columns)
delete[] c;
}
}
//---------------------------------------------------------------------------