-
Notifications
You must be signed in to change notification settings - Fork 0
/
DiskBuffer.cpp
135 lines (119 loc) · 3.39 KB
/
DiskBuffer.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
/*
* File: DiskBuffer.h
* Class: ICS 451
* Project #: 3
* Team Members: Bryce Groff, Brandon Grant, Emiliano Miranda
* Author: Bryce Groff
* Created Date: 04-23-09
* Desc: Creates a buffer created on disk that can be written to.
*/
#include <iostream>
#include <fstream>
#include <inttypes.h>
#include <sys/mman.h>
#include "DiskBuffer.h"
/*!
\param fileName The filename that will be used to store the information.
\param fileSize The total size of the file to be stored.
\param nextSeq The starting sequence number.
*/
DiskBuffer::DiskBuffer(string &fileName, uint64_t fileSize, uint64_t nextSeq)
: mFileName(fileName), mFileSize(fileSize), mNextSeq(nextSeq)
{
// Open the file for writing
try {
mFile.open(mFileName.c_str(), fstream::out);
}
catch (ios_base::failure &e) {
cerr<<"DiskBuffer [Constructor]: "<<e.what()<<endl;
}
}
DiskBuffer::~DiskBuffer()
{
mFile.close();
}
/*!
\brief Adds data to the DiskBuffer. If the data is in order, the
data will be added and the out of order cache will be iterated over
to find any data that may come next. If the data is out of order it will be
put in the OutOfSeqCache
\sa Data
\param &packet The packet that you wish to add to the buffer.
\return The amount of data saved to disk.
*/
uint64_t DiskBuffer::Add(Data &packet)
{
uint64_t fSeqNum = packet.mSeqNum;
uint32_t fSize = packet.mPacketSize;
// If the sequence number is the number that we
// are expecting to receive then process the data.
if (mNextSeq == fSeqNum) {
// TODO: This can probably be finner grain.
//mWriteLock.Lock();
try {
mFile.write(packet.mData, (streamsize)fSize);
}
catch (ios_base::failure &e) {
cerr<<"DiskBuffer [Add]: "<<e.what()<<endl;
}
// Increment the current sequence number by the size of the packet.
// This should be the next sequence number. Then loop over the out
// of order cache and add as much data as we have.
mNextSeq += fSize;
Data *fNext = mOutOfSeqCache.GetData(mNextSeq);
while (fNext != NULL) {
// Write the data.
mFile.flush();
mFile.write(fNext->mData, (streamsize)fNext->mPacketSize);
fSize += fNext->mPacketSize;
// Increment the pointer
mNextSeq += fNext->mPacketSize;
// Free the memory.
delete [] fNext->mData;
delete fNext;
fNext = mOutOfSeqCache.GetData(mNextSeq);
}
//mWriteLock.Unlock();
}
// If the sequence number is greater than the number we are expecting
// then add the data to the out of order cache.
else if (mNextSeq < fSeqNum) {
// Lock so we are not adding data while trying to remove above.
//mWriteLock.Lock();
mOutOfSeqCache.Add(packet);
//mWriteLock.Unlock();
//fSize = 0;
}
// return how many bytes we saved to disk.
return fSize;
}
/*!
\brief Returns the next sequence number that DiskBuffer is expecting.
\return mNextSeq
*/
uint64_t DiskBuffer::GetNextSeq()
{
return mNextSeq;
}
/*!
\brief Returns the window size to throttle back the sender.
\return the window size
*/
uint32_t DiskBuffer::GetWindowSize()
{
//TODO: Make this do something useful
return 0xFFFFFFFF;
}
/*!
\brief Flushes all the data that is in memory but not yet on the disk.
\return Nothing
*/
void DiskBuffer::Flush()
{
try {
mFile.flush();
}
catch (ios_base::failure &e) {
cerr<<"DiskBuffer [Flush]: "<<e.what()<<endl;
}
}