Created
January 23, 2023 17:03
-
-
Save M0nteCarl0/58f2be01f260094b65f1b7ed990bde9c to your computer and use it in GitHub Desktop.
C++ File RAM Cache implentation for high speed detectors
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "CriticalSection.h" | |
CriticalSection::CriticalSection() { | |
Init(); | |
} | |
CriticalSection::CriticalSection(const char * Decription) { | |
Init(); | |
_Description = Decription; | |
} | |
const char * CriticalSection::GetDescription(void) { | |
return _Description.data(); | |
} | |
CriticalSection::~CriticalSection() { | |
} | |
void CriticalSection::Enter(void) { | |
EnterCriticalSection(&_Sec); | |
} | |
void CriticalSection::Leave(void) { | |
LeaveCriticalSection(&_Sec); | |
} | |
void CriticalSection::Init(void) { | |
InitializeCriticalSection(&_Sec); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _CS_ | |
#define _CS_ | |
#include <Windows.h> | |
#include <string> | |
class CriticalSection { | |
public: | |
CriticalSection(); | |
CriticalSection(const char* Decription); | |
const char* GetDescription(void); | |
~CriticalSection(); | |
void Enter(void); | |
void Leave(void); | |
private: | |
void Init(void); | |
CRITICAL_SECTION _Sec; | |
std::string _Description; | |
}; | |
#endif | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "RAM_Cache.h" | |
RAM_Cache::RAM_Cache(void) { | |
_MaximumFileInStorage = 0; | |
_IsFull = 0; | |
_SizeStorageInBytes = 0; | |
_MaximumStorageInBytes = 0; | |
_LastFindedFileIndex = 0; | |
_ErrorCode = RAM_CacheError_EmptyStorage; | |
_WritePolicy = RAM_Cache_WritePolicyNormal; | |
_FileIterator = 0; | |
} | |
RAM_Cache::~RAM_Cache(void) { | |
Clean(); | |
} | |
bool RAM_Cache::FindFile(const char* FilePath) { | |
bool Flag = false; | |
if (_Storage.size() != 0) { | |
if (FilePath != nullptr) { | |
_ErrorCode = RAM_CacheError_FileNotFound; | |
for (size_t i = 0; i < _Storage.size(); i++) { | |
if (_Storage[i].PathToFile != nullptr) { | |
if (strcmp(_Storage[i].PathToFile, FilePath) == 0) { | |
Flag = true; | |
_ErrorCode = RAM_CacheError_OK; | |
_LastFindedFileIndex = i; | |
break; | |
} | |
} | |
} | |
} | |
else { | |
_ErrorCode = RAM_CacheError_EmptyFilePath; | |
} | |
} | |
else { | |
_ErrorCode = RAM_CacheError_EmptyStorage; | |
} | |
return Flag; | |
} | |
void RAM_Cache::ChangeFileData(const char * FilePath, uint8_t * BuffeData, size_t FileSize) { | |
if (FindFile(FilePath)) { | |
if (_Storage[_LastFindedFileIndex].Buffer) { | |
if (_Storage[_LastFindedFileIndex].FileSize > FileSize) { | |
memcpy(_Storage[_LastFindedFileIndex].Buffer, BuffeData, FileSize); | |
} | |
} | |
else { | |
delete[] _Storage[_LastFindedFileIndex].Buffer; | |
try { | |
_Storage[_LastFindedFileIndex].Buffer = new uint8_t[FileSize]; | |
memcpy(_Storage[_LastFindedFileIndex].Buffer, BuffeData, FileSize); | |
} | |
catch (const std::bad_alloc) { | |
_ErrorCode = RAM_CacheError_MemoryAllocationForFileFalied; | |
} | |
} | |
} | |
} | |
void RAM_Cache::RemoveFile(const char * FilePath){ | |
if (FindFile(FilePath)) { | |
delete[] _Storage[_LastFindedFileIndex].Buffer; | |
delete[] _Storage[_LastFindedFileIndex].PathToFile; | |
_Storage.erase(_Storage.begin() + _LastFindedFileIndex); | |
_Storage.shrink_to_fit(); | |
} | |
} | |
bool RAM_Cache::AddFile(const char * FilePath, uint8_t * BuffeData, size_t FileSize) { | |
bool Flag = false; | |
RAM_CacheNode Node; | |
if (!FindFile(FilePath)) { | |
if (FilePath) { | |
if (BuffeData) { | |
if (_WritePolicy == RAM_Cache_WritePolicyNormal) { | |
if (_MaximumFileInStorage != 0) { | |
if (_MaximumFileInStorage == _Storage.size()) { | |
_ErrorCode = RAM_CacheError_NotWritenbyLimitFileCount; | |
Flag = false; | |
return Flag; | |
} | |
} | |
if (_MaximumStorageInBytes != 0) { | |
if (_SizeStorageInBytes == _MaximumStorageInBytes) { | |
_ErrorCode = RAM_CacheError_NotWritenbyLimitMemoryUsage; | |
Flag = false; | |
return Flag; | |
} | |
} | |
Node.PathToFile = new(nothrow)char[strlen(FilePath) + 1]; | |
Node.Buffer = new(nothrow)uint8_t[FileSize]; | |
if (Node.PathToFile && Node.Buffer) { | |
Node.FileSize = FileSize; | |
strcpy(Node.PathToFile, FilePath); | |
memcpy(Node.Buffer, BuffeData, FileSize); | |
_ErrorCode = RAM_CacheError_OK; | |
Flag = true; | |
_Storage.push_back(Node); | |
_SizeStorageInBytes += FileSize; | |
} | |
else { | |
Flag = false; | |
_ErrorCode = RAM_CacheError_MemoryAllocationForFileFalied; | |
} | |
} | |
if (_WritePolicy == RAM_Cache_WritePolicyOverwriteWhenFull) { | |
if (_MaximumFileInStorage != 0) { | |
if (_MaximumFileInStorage > _Storage.size()) { | |
_IsFull = 0; | |
} | |
else { | |
_FileIterator = 0; | |
_IsFull = 1; | |
} | |
} | |
else { | |
_ErrorCode = RAM_CacheError_NotWritenbyEmptyLimitFileCount; | |
Flag = false; | |
return Flag; | |
} | |
if (_MaximumStorageInBytes != 0) { | |
if (_SizeStorageInBytes < _MaximumStorageInBytes) { | |
_IsFull = 0; | |
} | |
else { | |
_FileIterator = 0; | |
_IsFull = 1; | |
} | |
} | |
if (!_IsFull) { | |
Node.PathToFile = new(nothrow)char[strlen(FilePath) + 1]; | |
Node.Buffer = new(nothrow) uint8_t[FileSize]; | |
if (Node.PathToFile && Node.PathToFile) { | |
Node.FileSize = FileSize; | |
strcpy(Node.PathToFile, FilePath); | |
memcpy(Node.Buffer, BuffeData, FileSize); | |
_ErrorCode = RAM_CacheError_OK; | |
Flag = true; | |
_Storage.push_back(Node); | |
_SizeStorageInBytes += FileSize; | |
} | |
else { | |
_ErrorCode = RAM_CacheError_MemoryAllocationForFileFalied; | |
Flag = false; | |
} | |
} | |
else { | |
if (_FileIterator == _Storage.size() - 1) { _FileIterator = 0; } | |
if (_Storage[_FileIterator].Buffer) { | |
delete[] _Storage[_FileIterator].Buffer; | |
_SizeStorageInBytes -= _Storage[_FileIterator].FileSize; | |
} | |
if (_Storage[_FileIterator].PathToFile) { | |
delete[] _Storage[_FileIterator].PathToFile; | |
} | |
_Storage[_FileIterator].Buffer = new (nothrow) uint8_t[FileSize]; | |
_Storage[_FileIterator].PathToFile = new(nothrow) char[strlen(FilePath) + 1]; | |
if (_Storage[_FileIterator].Buffer && _Storage[_FileIterator].PathToFile) { | |
_Storage[_FileIterator].FileSize = FileSize; | |
strcpy(_Storage[_FileIterator].PathToFile, FilePath); | |
memcpy(_Storage[_FileIterator].Buffer, BuffeData, FileSize); | |
_ErrorCode = RAM_CacheError_OK; | |
_SizeStorageInBytes += FileSize; | |
Flag = true; | |
_FileIterator++; | |
} | |
else { | |
_Storage[_FileIterator].FileSize = 0; | |
_ErrorCode = RAM_CacheError_MemoryAllocationForFileFalied; | |
Flag = false; | |
} | |
} | |
} | |
} | |
else { | |
_ErrorCode = RAM_CacheError_EmptyFileBuffer; | |
} | |
} | |
else { | |
_ErrorCode = RAM_CacheError_EmptyFilePath; | |
} | |
} | |
return Flag; | |
} | |
bool RAM_Cache::CacheBLOBData(const char* BlobName, uint8_t* BuffeData, size_t FileSize) { | |
return AddFile(BlobName, BuffeData, FileSize); | |
} | |
void RAM_Cache::Clean(void) { | |
_ErrorCode = RAM_CacheError_EmptyStorage; | |
if (_Storage.size() != 0) { | |
for (size_t i = 0; i < _Storage.size(); i++) { | |
RemoveFile(_Storage[i].PathToFile); | |
} | |
} | |
_Storage.clear(); | |
} | |
uint8_t * RAM_Cache::GetFileData(const char * FilePath, size_t& FileSize) { | |
uint8_t * Data = nullptr; | |
FileSize = 0; | |
if (FindFile(FilePath)) { | |
FileSize = _Storage[_LastFindedFileIndex].FileSize; | |
Data = _Storage[_LastFindedFileIndex].Buffer; | |
} | |
return Data; | |
} | |
size_t RAM_Cache::GetMaximumFileInStorage(void) { | |
return _MaximumFileInStorage; | |
} | |
size_t RAM_Cache::GetSizeStorageSizeInBytes(void) { | |
return _SizeStorageInBytes; | |
} | |
size_t RAM_Cache::GetMaximumStorageInBytes(void) { | |
return _MaximumStorageInBytes; | |
} | |
void RAM_Cache::SetMaximumFileInStorage(size_t MaximumFileInStorage) { | |
this->_MaximumFileInStorage = MaximumFileInStorage; | |
} | |
void RAM_Cache::SetWritePolicy(RAM_Cache_WritePolicy WritePolicy) { | |
this->_WritePolicy = WritePolicy; | |
} | |
vector<string> RAM_Cache::GetFileNameList(void) { | |
_StoredFileNamesList.clear(); | |
if (_Storage.size() != 0) { | |
for (size_t i = 0; i < _Storage.size(); i++) { | |
_StoredFileNamesList.push_back(_Storage[i].PathToFile); | |
} | |
} | |
return _StoredFileNamesList; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _RAM_CACHE_ | |
#define _RAM_CACHE_ | |
#include <memory.h> | |
#include <vector> | |
#include <stdint.h> | |
#include "CriticalSection.h" | |
using namespace std; | |
typedef struct RAM_CacheNode { | |
char* PathToFile; | |
uint8_t* Buffer; | |
size_t FileSize; | |
}RAM_CacheNode; | |
enum RAM_Cache_WritePolicy { | |
RAM_Cache_WritePolicyNormal, | |
RAM_Cache_WritePolicyOverwriteWhenFull, | |
RAM_Cache_WritePolicyMaximumDRAMUsage, | |
}; | |
enum RAM_CacheError { | |
RAM_CacheError_OK, | |
RAM_CacheError_FileNotFound, | |
RAM_CacheError_EmptyStorage, | |
RAM_CacheError_EmptyFilePath, | |
RAM_CacheError_EmptyFileBuffer, | |
RAM_CacheError_MemoryAllocationForFileFalied, | |
RAM_CacheError_NotWritenbyMemoryNotEnogh, | |
RAM_CacheError_NotWritenbyLimitFileCount, | |
RAM_CacheError_NotWritenbyEmptyLimitFileCount, | |
RAM_CacheError_NotWritenbyLimitMemoryUsage, | |
RAM_CacheError_NotWritenbybyEmptyLimitMemoryUsage, | |
}; | |
/************************************************************************************************* | |
* Module for work with RAM Buffer(POSIX) | |
* | |
* Initial version: 13.07.19 | |
* last update: 19.11.20 | |
* | |
* | |
* | |
***************************************************************************************************/ | |
class RAM_Cache { | |
public: | |
RAM_Cache(void); | |
~RAM_Cache(void); | |
bool FindFile(const char* FilePath); | |
void ChangeFileData(const char* FilePath, uint8_t* BuffeData, size_t FileSize); | |
void RemoveFile(const char* FilePath); | |
bool AddFile(const char* FilePath, uint8_t* BuffeData, size_t FileSize); | |
bool CacheBLOBData(const char* BlobName, uint8_t* BuffeData, size_t FileSize); | |
void Clean(void); | |
uint8_t* GetFileData(const char* FilePath, size_t& FileSize); | |
size_t GetMaximumFileInStorage(void); | |
size_t GetSizeStorageSizeInBytes(void); | |
size_t GetMaximumStorageInBytes(void); | |
void SetMaximumFileInStorage(size_t MaximumFileInStorage); | |
void SetWritePolicy(RAM_Cache_WritePolicy WritePolicy); | |
RAM_CacheError GetErrorCode(void) { return _ErrorCode;}; | |
vector<string> GetFileNameList(void); | |
private: | |
vector<RAM_CacheNode> _Storage; | |
vector<string> _StoredFileNamesList; | |
CriticalSection _Section; | |
size_t _MaximumFileInStorage; | |
size_t _IsFull; | |
size_t _SizeStorageInBytes; | |
size_t _MaximumStorageInBytes; | |
size_t _LastFindedFileIndex; | |
size_t _FileIterator; | |
RAM_CacheError _ErrorCode; | |
RAM_Cache_WritePolicy _WritePolicy; | |
}; | |
#endif // DEBUG |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment