26 #ifndef _MMAPSTOREBUFFER_H_ 27 #define _MMAPSTOREBUFFER_H_ 32 #include <sys/types.h> 60 size_t initialSize_ = AMPS_MEMORYBUFFER_DEFAULT_LENGTH)
62 , _mapFile(INVALID_HANDLE_VALUE), _file(INVALID_HANDLE_VALUE)
64 _file = CreateFileA(fileName_.c_str(), GENERIC_READ | GENERIC_WRITE, 0,
65 NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
66 if ( _file == INVALID_HANDLE_VALUE )
68 std::ostringstream os;
69 os <<
"Failed to create file " << fileName_ <<
" for MMapStoreBuffer";
72 LARGE_INTEGER liFileSize;
73 if (GetFileSizeEx(_file, &liFileSize) == 0)
75 std::ostringstream os;
76 os <<
"Failure getting file size of " << fileName_ <<
" for MMapStoreBuffer";
80 size_t fileSize = liFileSize.QuadPart;
82 size_t fileSize = liFileSize.LowPart;
84 _setSize( initialSize_ > fileSize ?
85 initialSize_ : fileSize);
89 size_t initialSize_ = AMPS_MEMORYBUFFER_DEFAULT_LENGTH)
92 _fd = ::open(fileName_.c_str(), O_CREAT | O_RDWR, (mode_t)0644);
94 memset(&statBuf, 0,
sizeof(statBuf));
95 if (fstat(_fd, &statBuf) == -1)
97 std::ostringstream os;
98 os <<
"Failed to stat file " << fileName_ <<
" for MMapStoreBuffer";
101 bool recovery = (size_t)statBuf.st_size >= initialSize_;
102 _setSize(recovery ? (
size_t)statBuf.st_size
120 FlushFileBuffers(_file);
121 UnmapViewOfFile(_buffer);
122 CloseHandle(_mapFile);
124 _mapFile = INVALID_HANDLE_VALUE;
125 _file = INVALID_HANDLE_VALUE;
127 munmap(_buffer, _bufferLen);
137 if (_buffer != NULL && _bufferLen)
140 if (!FlushViewOfFile(_buffer, _bufferPos))
142 if (msync(_buffer, _bufferPos, MS_ASYNC) != 0)
145 std::ostringstream os;
146 os <<
"Failed to sync mapped memory; buffer: " << (size_t)_buffer
147 <<
" pos: " << _bufferPos;
158 void _setSize(
size_t newSize_,
bool recovery_ =
false)
165 static const size_t pageSize = getPageSize();
166 size_t sz = (newSize_ + pageSize - 1) / pageSize * pageSize;
168 if (_mapFile != INVALID_HANDLE_VALUE && _mapFile != NULL)
170 FlushFileBuffers(_file);
171 UnmapViewOfFile(_buffer);
172 CloseHandle(_mapFile);
175 _mapFile = CreateFileMapping( _file, NULL, PAGE_READWRITE, (DWORD)((sz >> 32) & 0xffffffff), (DWORD)sz, NULL);
177 _mapFile = CreateFileMapping( _file, NULL, PAGE_READWRITE, 0, (DWORD)sz, NULL);
179 if (_mapFile == INVALID_HANDLE_VALUE || _mapFile == NULL)
183 error(
"Failed to create map of log file");
187 _buffer = (
char*)MapViewOfFile(_mapFile, FILE_MAP_ALL_ACCESS, 0, 0, sz);
190 std::ostringstream os;
191 os <<
"Failed to map log file to memory; buffer: " << (size_t)_buffer <<
" length: " << sz <<
" previous size: " << _bufferLen;
201 if (lseek(_fd, (off_t)sz - 1, SEEK_SET) == -1)
203 std::ostringstream os;
204 os <<
"Seek failed for buffer extension; buffer: " << (size_t)_buffer
205 <<
" length: " << _bufferLen <<
" pos: " << _bufferPos
206 <<
" requested new size: " << newSize_;
211 if (::write(_fd,
"", 1) == -1)
213 std::ostringstream os;
214 os <<
"Failed to grow buffer; buffer: " << (size_t)_buffer <<
" length: " 215 << _bufferLen <<
" pos: " << _bufferPos <<
" requested new size: " 225 result = mmap(0, sz, PROT_WRITE | PROT_READ, MAP_SHARED, _fd, 0);
227 else if (_bufferLen < sz)
230 result = mremap(_buffer, _bufferLen, sz, MREMAP_MAYMOVE);
232 munmap(_buffer, _bufferLen);
233 result = mmap(0, sz, PROT_WRITE | PROT_READ, MAP_SHARED, _fd, 0);
236 if (result == MAP_FAILED || result == NULL)
238 std::ostringstream os;
239 os <<
"Failed to map log file to memory; buffer: " 240 << (size_t)_buffer <<
" length: " << sz
241 <<
" previous size: " << _bufferLen;
248 _buffer = (
char*)result;
258 void error(
const std::string & message)
260 std::ostringstream os;
262 const size_t errorBufferSize = 1024;
263 char errorBuffer[errorBufferSize];
264 memset(errorBuffer, 0, errorBufferSize);
265 strerror_s(errorBuffer, errorBufferSize, errno);
266 os << message <<
". Error is " << errorBuffer;
268 os << message <<
". Error is " << strerror(errno);
270 throw StoreException(os.str());
279 static size_t getPageSize()
281 static size_t pageSize;
285 SYSTEM_INFO SYS_INFO;
286 GetSystemInfo(&SYS_INFO);
287 pageSize = SYS_INFO.dwPageSize;
289 pageSize = (size_t)sysconf(_SC_PAGESIZE);
291 if (pageSize == (
size_t)-1)
304 #endif //_MMAPSTOREBUFFER_H_ virtual void setSize(size_t newSize_)
Set the size for the buffer.
Definition: MMapStoreBuffer.hpp:153
MMapStoreBuffer(const std::string &fileName_, size_t initialSize_=AMPS_MEMORYBUFFER_DEFAULT_LENGTH)
Create an MMapStoreBuffer using fileName_ as the name of the memory mapped file used for storage...
Definition: MMapStoreBuffer.hpp:88
A Buffer implementation that uses memory for storage.
Definition: MemoryStoreBuffer.hpp:50
Core type, function, and class declarations for the AMPS C++ client.
A Buffer implementation that uses a memory mapped file as its storage.
Definition: MMapStoreBuffer.hpp:49
Provides AMPS::MemoryStoreBuffer, used by an AMPS::HAClient to store messages in memory.
Definition: AMPSException.hpp:32