26 #ifndef _MMAPSTOREBUFFER_H_ 27 #define _MMAPSTOREBUFFER_H_ 32 #include <sys/types.h> 60 , _mapFile(INVALID_HANDLE_VALUE), _file(INVALID_HANDLE_VALUE)
62 _file = CreateFileA(fileName_.c_str(), GENERIC_READ | GENERIC_WRITE, 0,
63 NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
64 if( _file == INVALID_HANDLE_VALUE )
66 std::ostringstream os;
67 os <<
"Failed to create file " << fileName_ <<
" for MMapStoreBuffer";
70 LARGE_INTEGER liFileSize;
71 if(GetFileSizeEx(_file, &liFileSize) == 0)
73 std::ostringstream os;
74 os <<
"Failure getting file size of " << fileName_ <<
" for MMapStoreBuffer";
78 size_t fileSize = liFileSize.QuadPart;
80 size_t fileSize = liFileSize.LowPart;
82 _setSize( AMPS_MEMORYBUFFER_DEFAULT_LENGTH > fileSize ?
83 AMPS_MEMORYBUFFER_DEFAULT_LENGTH : fileSize);
86 _fd = ::open(fileName_.c_str(), O_CREAT | O_RDWR, (mode_t)0644);
88 memset(&statBuf, 0,
sizeof(statBuf));
89 if(fstat(_fd, &statBuf) == -1)
91 std::ostringstream os;
92 os <<
"Failed to stat file " << fileName_ <<
" for MMapStoreBuffer";
95 _bufferLen = (size_t)statBuf.st_size;
96 _setSize(statBuf.st_size > (ssize_t)AMPS_MEMORYBUFFER_DEFAULT_LENGTH
97 ? (size_t)statBuf.st_size : AMPS_MEMORYBUFFER_DEFAULT_LENGTH);
111 FlushFileBuffers(_file);
112 UnmapViewOfFile(_buffer);
113 CloseHandle(_mapFile);
115 _mapFile = INVALID_HANDLE_VALUE;
116 _file = INVALID_HANDLE_VALUE;
118 munmap(_buffer, _bufferLen);
131 if(!FlushViewOfFile(_buffer, _bufferPos))
133 if(msync(_buffer, _bufferPos, MS_ASYNC) != 0)
136 std::ostringstream os;
137 os <<
"Failed to sync mapped memory; buffer: " << (size_t)_buffer
138 <<
" pos: " << _bufferPos;
149 void _setSize(
size_t newSize_)
154 size_t sz = newSize_ & (size_t)(~(getPageSize()-1));
160 if(_mapFile != INVALID_HANDLE_VALUE && _mapFile != NULL)
162 FlushFileBuffers(_file);
163 UnmapViewOfFile(_buffer);
164 CloseHandle(_mapFile);
167 _mapFile = CreateFileMapping( _file, NULL, PAGE_READWRITE, (DWORD)((sz >> 32) & 0xffffffff), (DWORD)sz, NULL);
169 _mapFile = CreateFileMapping( _file, NULL, PAGE_READWRITE, 0, (DWORD)sz, NULL);
171 if(_mapFile == INVALID_HANDLE_VALUE || _mapFile == NULL)
175 error(
"Failed to create map of log file");
179 _buffer = (
char*)MapViewOfFile(_mapFile, FILE_MAP_ALL_ACCESS, 0, 0, sz);
182 std::ostringstream os;
183 os <<
"Failed to map log file to memory; buffer: " << (size_t)_buffer <<
" length: " << sz <<
" previous size: " << _bufferLen;
193 if(lseek(_fd, (off_t)sz-1, SEEK_SET) == -1)
195 std::ostringstream os;
196 os <<
"Seek failed for buffer extension; buffer: " << (size_t)_buffer
197 <<
" length: " << _bufferLen <<
" pos: " << _bufferPos
198 <<
" requested new size: " << newSize_;
201 if(::write(_fd,
"", 1) == -1)
203 std::ostringstream os;
204 os <<
"Failed to grow buffer; buffer: " << (size_t)_buffer <<
" length: " 205 << _bufferLen <<
" pos: " << _bufferPos <<
" requested new size: " 214 result = mmap(0, sz, PROT_WRITE|PROT_READ, MAP_SHARED, _fd, 0);
216 else if(_bufferLen < sz)
219 result = mremap(_buffer, _bufferLen, sz, MREMAP_MAYMOVE);
221 munmap(_buffer,_bufferLen);
222 result = mmap(0,sz,PROT_WRITE|PROT_READ,MAP_SHARED,_fd,0);
225 if(result == MAP_FAILED || result == NULL)
227 std::ostringstream os;
228 os <<
"Failed to map log file to memory; buffer: " 229 << (size_t)_buffer <<
" length: " << sz
230 <<
" previous size: " << _bufferLen;
235 _buffer = (
char*)result;
242 void error(
const std::string& message)
244 std::ostringstream os;
246 const size_t errorBufferSize = 1024;
247 char errorBuffer[errorBufferSize];
248 memset(errorBuffer,0,errorBufferSize);
249 strerror_s(errorBuffer,errorBufferSize,errno);
250 os << message <<
". Error is " << errorBuffer;
252 os << message <<
". Error is " << strerror(errno);
254 throw StoreException(os.str());
263 static size_t getPageSize()
265 static size_t pageSize;
269 SYSTEM_INFO SYS_INFO;
270 GetSystemInfo(&SYS_INFO);
271 pageSize = SYS_INFO.dwPageSize;
273 pageSize = (size_t)sysconf(_SC_PAGESIZE);
283 #endif //_MMAPSTOREBUFFER_H_ virtual void setSize(size_t newSize_)
Set the size for the buffer.
Definition: MMapStoreBuffer.hpp:144
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
MMapStoreBuffer(const std::string &fileName_)
Create an MMapStoreBuffer using fileName_ as the name of the memory mapped file used for storage...
Definition: MMapStoreBuffer.hpp:57
Provides AMPS::MemoryStoreBuffer, used by an AMPS::HAClient to store messages in memory.
Definition: ampsplusplus.hpp:103