-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDiskPageReadWriter.cpp
More file actions
125 lines (109 loc) · 3.04 KB
/
DiskPageReadWriter.cpp
File metadata and controls
125 lines (109 loc) · 3.04 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "DiskPageReadWriter.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string>
#include <cstring>
DiskPageReadWriter::DiskPageReadWriter(const char* file, GlobalConfiguration *_globConf)
: m_fd(-1)
, m_globConf(_globConf)
{
if (!m_globConf) {
throw std::string("globConf can't be null");
}
//check file existence
if (access(file, F_OK) == -1) { // No file
m_globConf->initialize(
m_globConf->desiredPageCount(),
m_globConf->desiredPageSize(),
m_globConf->desiredRootNodePageNumber(),
m_globConf->desiredCacheSize(),
m_globConf->desiredJournalPath());
m_fd = creat(file, 0644);
if (m_fd == -1) {
throw std::string("Error creating file");
}
if (ftruncate(m_fd, m_globConf->databaseSize()) == -1) {
::close(m_fd);
throw std::string("Error resizing file to needed size");
}
// Preallocating global configuration page and root node first page >
m_bitset.initialize(
m_globConf,
{0, m_globConf->rootNodePageNumber()},
m_globConf->rootNodePageNumber() + 1
);
writeGlobConfAndBitset();
::close(m_fd);
m_fd = open(file, O_RDWR);
} else {
m_fd = open(file, O_RDWR);
if (m_fd == -1) {
throw std::string("Error opening file");
}
m_globConf->readFromFile(m_fd);
Page firstPage(0, m_globConf->pageSize());
read(firstPage);
firstPage.seek(0);
m_globConf->skipDataOnPage(firstPage);
m_bitset.read(m_globConf, firstPage, *this);
}
}
void DiskPageReadWriter::writeGlobConfAndBitset()
{
Page firstPage(0, m_globConf->pageSize());
firstPage.seek(0);
m_globConf->writeToPage(firstPage);
m_bitset.write(firstPage, *this);
write(firstPage);
}
size_t DiskPageReadWriter::allocatePageNumber()
{
size_t res = m_bitset.freePageNumber();
m_bitset.set(res, 1);
writeGlobConfAndBitset(); // HACK: dirty hack!
return res;
}
void DiskPageReadWriter::deallocatePageNumber(const size_t &number)
{
m_bitset.set(number, 0);
writeGlobConfAndBitset(); // HACK: dirty hack!
}
void DiskPageReadWriter::read(Page &p)
{
if (p.number() >= m_globConf->pageCount()) {
throw std::string("Invalid page number read\n");
}
if (lseek(m_fd, p.number() * m_globConf->pageSize(), SEEK_SET) == -1) {
throw std::string("Error seeking page");
}
if (::read(m_fd, p.rawData(), m_globConf->pageSize()) != m_globConf->pageSize()) {
throw std::string("Error reading page");
}
}
void DiskPageReadWriter::write(const Page &p)
{
if (p.number() >= m_globConf->pageCount()) {
throw std::string("Invalid page number write\n");
}
if (lseek(m_fd, p.number() * m_globConf->pageSize(), SEEK_SET) == -1) {
throw std::string("Error seeking page");
}
if (::write(m_fd, p.rawData(), m_globConf->pageSize()) != m_globConf->pageSize()) {
throw std::string("Error writing page");
}
}
void DiskPageReadWriter::flush()
{
writeGlobConfAndBitset();
}
void DiskPageReadWriter::close()
{
if (m_fd != -1) {
flush();
if (::close(m_fd) == -1) {
throw std::string("Error closing file");
}
}
}