-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpc_disk_storage.cpp
146 lines (113 loc) · 4 KB
/
pc_disk_storage.cpp
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include "pc_disk_storage.h"
#include <iostream>
#include <tuple>
using namespace std;
PCDiskStorage::PCDiskStorage(unsigned int totalSize, unsigned int sizeOfBlock)
{
this->totalSize = totalSize;
this->sizeOfBlock = sizeOfBlock;
unsigned char *storagePtr = nullptr;
this->storagePtr = new unsigned char[totalSize];
this->blockPtr = nullptr;
this->numAllocatedRecords = 0;
this->numAllocatedBlocks = 0;
this->numAvailableBlocks = totalSize / sizeOfBlock;
this->currentBlockSpaceUsed = 0;
}
PCDiskStorage::~PCDiskStorage()
{
delete storagePtr;
storagePtr = nullptr;
}
int PCDiskStorage::searchNumVotes(unsigned int targetNumVotes)
{
int numBlocksAccessed = 0;
int numRecordsFound = 0;
// Iterate through all allocated blocks
for (auto block : blockList)
{
numBlocksAccessed++;
// Iterate through all records in the block
for (unsigned int offset = 0; offset < sizeOfBlock; offset += sizeof(Record))
{
Record* record = (Record*)(block + offset);
// If record is not deleted and numVotes matches target value, increment count
if (!record->deleted && record->numVotes == targetNumVotes)
{
numRecordsFound++;
}
}
}
// cout << "Number of data blocks accessed: " << numBlocksAccessed << endl;
// cout << "Number of records found: " << numRecordsFound << endl;
return numBlocksAccessed;
}
int PCDiskStorage::searchNumVotesBetween(unsigned int minNumVotes, unsigned int maxNumVotes) {
int blocksAccessed = 0;
int recordsSearched = 0;
// Iterate through all allocated blocks
for (auto block : blockList) {
Record *currentRecord = (Record *)block;
int numRecordsInBlock = sizeOfBlock / sizeof(Record);
// Iterate through all records in block
for (int i = 0; i < numRecordsInBlock; i++) {
if (currentRecord[i].deleted)
continue;
if (currentRecord[i].numVotes >= minNumVotes && currentRecord[i].numVotes <= maxNumVotes) {
// Record matches search criteria
recordsSearched++;
}
}
blocksAccessed++;
}
// cout << "Records found: " << recordsSearched << endl;
// cout << "Blocks accessed: " << blocksAccessed << endl;
return blocksAccessed;
}
int PCDiskStorage::deleteARecord(unsigned char *blockAddress, unsigned int offset, unsigned int recordSize)
try
{
fill(blockAddress + offset, blockAddress + offset + recordSize, '\0');
unsigned char *recordAddress = (unsigned char *)(blockAddress + offset);
recordList.remove(recordAddress);
numAllocatedRecords -= 1;
return 1;
}
catch (exception &e)
{
cout << "The exception:" << e.what() << endl;
cout << "Unsuccessful deletion" << endl;
return 0;
}
tuple<void *, unsigned int> PCDiskStorage::allocateARecord(unsigned int recordSize)
{
if ((numAllocatedBlocks == 0) || (recordSize > (sizeOfBlock - currentBlockSpaceUsed)))
{
if (!allocateABlock())
throw "All the blocks have been allocated and there is no more free space in the blocks.";
}
if (recordSize > sizeOfBlock)
{
throw "We are unable to allocate a record as the record size is biger than the size of the block.";
}
tuple<void *, unsigned int> recordAddress(blockPtr, currentBlockSpaceUsed);
recordList.push_back(blockPtr+currentBlockSpaceUsed);
numAllocatedRecords += 1;
currentBlockSpaceUsed += recordSize;
return recordAddress;
}
int PCDiskStorage::allocateABlock()
{
if (numAvailableBlocks <= 0)
{
cout << "Unsuccessful allocation" << endl;
return 0;
}
blockPtr = (numAllocatedBlocks * sizeOfBlock) + storagePtr;
numAllocatedBlocks += 1;
blockList.push_back(blockPtr);
numAvailableBlocks -= 1;
currentBlockSpaceUsed = 0;
cout << "Data block: " << numAllocatedBlocks << "" << endl;
return 1;
}