22 #include "MCDataStorage.hpp" 24 #include "MCBinaryData.hpp" 25 #include "MCDataContainer.hpp" 27 #include "MCThreadLocalData.hpp" 28 #include "MCZipper.hpp" 30 #include <boost/archive/binary_iarchive.hpp> 31 #include <boost/archive/binary_oarchive.hpp> 32 #include <boost/iostreams/device/back_inserter.hpp> 33 #include <boost/iostreams/stream.hpp> 42 void CheckStaticDataStorageVariables()
44 if (unlikely(!Verbose.get()))
46 Verbose.reset(
new bool);
57 CheckStaticDataStorageVariables();
65 MCDataStorage::~MCDataStorage()
103 printf(
"Containers (%d): ", (
int)ContainerNames.size());
104 for (
unsigned int i = 0; i < ContainerNames.size(); ++i)
105 printf(
"%s, ", ContainerNames[i].c_str());
113 std::ifstream InputFileStream(file_name.c_str(), std::ios::binary);
115 if (!InputFileStream.is_open())
117 MC_WARNING(
"Unable to open file to load binary data: %s", file_name.c_str());
120 InputFileStream.seekg(0, std::ios::end);
121 int FileSize = (int)InputFileStream.tellg();
123 InputFileStream.seekg(0, std::ios::beg);
125 InputFileStream.close();
127 MC_WARNING(
"Incompatible encoded data storage file (%s)", file_name.c_str());
137 std::ofstream OutputFileStream(file_name.c_str(), std::ios::out | std::ios::binary);
139 if (!OutputFileStream.is_open())
141 MC_WARNING(
"Unable to create file to save binary data: %s", file_name.c_str());
145 OutputFileStream.flush();
146 OutputFileStream.close();
148 MC_WARNING(
"Unable to save encoded data storage file (%s)", file_name.c_str());
160 boost::iostreams::basic_array_source<char> Source((
char*)data.
GetData(), (std::size_t)data.
GetSize());
161 boost::iostreams::stream<boost::iostreams::basic_array_source<char> > InStream(Source);
165 MC_WARNING(
"Incompatible encoded data storage version");
177 std::vector<char> TempBuffer;
179 boost::iostreams::stream<boost::iostreams::back_insert_device<std::vector<char> > > OutStream(TempBuffer);
184 memcpy(BinaryData->
GetData(), &TempBuffer[0], TempBuffer.size());
191 eos::portable_iarchive* InputPArchive =
nullptr;
192 boost::archive::binary_iarchive* InputArchive =
nullptr;
193 std::string DataStorageID;
197 InputPArchive =
new eos::portable_iarchive(input_stream);
198 *InputPArchive & DataStorageID;
200 InputArchive =
new boost::archive::binary_iarchive(input_stream);
201 *InputArchive & DataStorageID;
205 MC_WARNING(
"The archive is not a data storage.");
206 delete InputPArchive;
212 *InputArchive &
Name;
214 *InputPArchive &
Name;
217 while (input_stream.tellg() < max_bytes)
219 std::string ContainerName;
221 bool Compressed =
false;
225 *InputArchive & ContainerName;
227 *InputArchive & Compressed;
228 *InputArchive & *ContainerData;
230 *InputPArchive & ContainerName;
232 *InputPArchive & Compressed;
233 *InputPArchive & *ContainerData;
252 delete ContainerData;
253 ContainerData =
nullptr;
258 delete InputPArchive;
265 eos::portable_oarchive* OutputPArchive =
nullptr;
266 boost::archive::binary_oarchive* OutputArchive =
nullptr;
270 OutputPArchive =
new eos::portable_oarchive(output_stream);
272 *OutputPArchive &
Name;
274 OutputArchive =
new boost::archive::binary_oarchive(output_stream);
276 *OutputArchive &
Name;
281 bool Encoded =
false;
285 if (container.first == container2.first)
288 delete container2.second;
289 container2.second = container.second->Encode();
295 BinaryContainers.insert(std::make_pair(container.first, container.second->Encode()));
303 bool Compressing = EncodedData->
GetSize() > 2000;
307 *OutputArchive & container.first;
309 *OutputArchive & Compressing;
311 *OutputPArchive & container.first;
313 *OutputPArchive & Compressing;
349 *OutputArchive & CompressedData;
351 *OutputPArchive & CompressedData;
356 *OutputArchive & *EncodedData;
358 *OutputPArchive & *EncodedData;
362 delete OutputPArchive;
363 delete OutputArchive;
375 MC::StringList FinalNames = MCGetContainerKeys<std::string>(
DataContainers);
376 MC::StringList OtherNames = MCGetContainerKeys<std::string>(
BinaryContainers);
378 for (
auto& name : OtherNames)
382 FinalNames.push_back(name);
386 std::sort(FinalNames.begin(), FinalNames.end());
395 if (container.first == container_name)
397 MC_WARNING(
"Can't add new container with the same name (%s)", container_name.c_str());
398 return MC::DataContainerSPtr();
403 if (container.first == container_name)
405 MC_WARNING(
"Can't add new container with the same name (%s)", container_name.c_str());
406 return MC::DataContainerSPtr();
411 DataContainers.insert(std::make_pair(container_name, NewContainer));
421 if (container.first == container_name)
422 return container.second;
427 if (container.first == container_name)
429 MC::DataContainerSPtr DataContainer(
DecodeContainer(*container.second));
431 return DataContainers.insert(std::make_pair(container.first, DataContainer)).first->second;
434 return MC::DataContainerSPtr();
442 if (iter->second.use_count() == 1)
444 bool Encoded =
false;
448 if (iter->first == container.first)
451 delete container.second;
452 container.second = iter->second->Encode();
458 BinaryContainers.insert(std::make_pair(iter->first, iter->second->Encode()));
462 MC_LOG(
"Storage: %s - drop container: %s",
Name.c_str(), iter->first.c_str());
477 if (iter->first == container_name)
481 MC_LOG(
"Storage: %s - remove container: %s",
Name.c_str(), iter->first.c_str());
490 if (iter->first == container_name)
494 MC_LOG(
"Storage: %s - remove container (binary): %s",
Name.c_str(), iter->first.c_str());
513 delete container.second;
515 BinaryContainers.clear();
521 CheckStaticDataStorageVariables();
522 *Verbose = new_state;
528 CheckStaticDataStorageVariables();
bool MCContainerContains(const U &container, const T &value)
Check if a container contains a value.
MCBinaryData * Encode()
Save the data storage into binary form.
void RemoveContainer(const std::string &container_name)
Remove a container from the data storage.
MC::DataContainerSPtr CreateContainer(const std::string &container_name)
Create and add a container to the data storage.
bool IsCompact() const
Check if the data storage is compact.
void LoadFromInputStream(std::istream &input_stream, unsigned int max_bytes)
Load the data storage from a stream.
bool Portable
Data storage type (portable/non-portable)
#define MC_WARNING(...)
Warning macro.
static bool IsVerbose()
Get the verbosity of the data storage domain.
static MCDataStorage * Decode(const MCBinaryData &data, bool portable=false)
Load the data storage from binary form.
void Clear()
Clear the data storage.
MC::DataContainerSPtr GetContainer(const std::string &container_name)
Get a container from the data storage.
static void DecompressQuickLz(const MCBinaryData &input_buffer, MCBinaryData &output_buffer, bool without_header=false)
Decompress data with QuickLZ algorithm.
static void SetVerbose(bool new_state)
Set the verbosity of the data storage domain.
MC::StringList GetContainerNames() const
Get the container names in the data storage.
void SetName(const std::string &name)
Set the data storage name.
Data storage with file support.
std::string Name
Storage name.
bool IsPortable() const
Check if the data storage is portable.
MC::StrDataContainerSPtrMap DataContainers
Data containers.
void DumpContainerNames() const
Dump container names.
static void DecompressZlib(const MCBinaryData &input_buffer, MCBinaryData &output_buffer)
Decompress data with zlib algorithm.
static MCDataContainer * Decode(const MCBinaryData &data, bool portable=false, MCDataContainer *instance=nullptr)
Load the data container from binary form.
bool SaveToFile(const std::string &file_name)
Save the data storage to a file.
void OptimizeCachedContainers()
Optimize cached containers.
unsigned char * GetData() const
Get direct access to the binary data.
MCDataStorage(const std::string &name, bool portable=false)
Class constructor.
MC::StrBinaryDataPtrMap BinaryContainers
Data containers in binary form.
A wrapper class to cover boost::thread_specific_ptr/folly::ThreadLocal API on certain targets...
static MC::CompressionsType DetectCompressionMethod(const MCBinaryData &input_buffer, MC::CompressionsType compression=MC::InvalidCompression)
Detect the compression method of a buffer.
std::string GetName() const
Get the data storage name.
static std::string VersionID
Version ID string.
#define MC_LOG(...)
Debug macro.
static void CompressZlib(const MCBinaryData &input_buffer, MCBinaryData &output_buffer, MC::CompressionLevelsType compression_level)
Compress data with zlib algorithm.
bool LoadFromFile(const std::string &file_name)
Load the data storage from a file.
void SaveToOutputStream(std::ostream &output_stream)
Save the data storage to a stream.
virtual MCDataContainer * DecodeContainer(const MCBinaryData &data)
Decode a container.
int GetSize() const
Get binary data size.