Move load from file functionality to Data class

This commit is contained in:
Sebastian Messmer 2014-12-05 08:08:45 +01:00
parent e32a84eb8e
commit c20b09030d
4 changed files with 65 additions and 33 deletions

View File

@ -3,8 +3,14 @@
#include <stdexcept> #include <stdexcept>
#include <fstream> #include <fstream>
using std::istream;
using std::ofstream; using std::ofstream;
using std::ifstream;
using std::ios; using std::ios;
using std::unique_ptr;
using std::make_unique;
namespace bf = boost::filesystem;
namespace blobstore { namespace blobstore {
namespace ondisk { namespace ondisk {
@ -16,6 +22,12 @@ Data::Data(size_t size)
} }
} }
Data::Data(Data &&rhs)
: _size(rhs._size), _data(rhs._data) {
// Make rhs invalid, so the memory doesn't get freed in its destructor.
rhs._data = nullptr;
}
Data::~Data() { Data::~Data() {
std::free(_data); std::free(_data);
_data = nullptr; _data = nullptr;
@ -33,10 +45,40 @@ size_t Data::size() const {
return _size; return _size;
} }
void Data::StoreToFile(const boost::filesystem::path &filepath) const { void Data::FillWithZeroes() {
std::memset(_data, 0, _size);
}
void Data::StoreToFile(const bf::path &filepath) const {
ofstream file(filepath.c_str(), ios::binary | ios::trunc); ofstream file(filepath.c_str(), ios::binary | ios::trunc);
file.write((const char*)_data, _size); file.write((const char*)_data, _size);
} }
unique_ptr<Data> Data::LoadFromFile(const bf::path &filepath) {
ifstream file(filepath.c_str(), ios::binary);
size_t size = _getStreamSize(file);
auto blob = make_unique<Data>(size);
blob->_readFromStream(file);
return blob;
}
size_t Data::_getStreamSize(istream &stream) {
auto current_pos = stream.tellg();
//Retrieve length
stream.seekg(0, stream.end);
auto endpos = stream.tellg();
//Restore old position
stream.seekg(current_pos, stream.beg);
return endpos - current_pos;
}
void Data::_readFromStream(istream &stream) {
stream.read((char*)_data, _size);
}
} /* namespace ondisk */ } /* namespace ondisk */
} /* namespace blobstore */ } /* namespace blobstore */

View File

@ -7,6 +7,7 @@
#include "fspp/utils/macros.h" #include "fspp/utils/macros.h"
#include <boost/filesystem/path.hpp> #include <boost/filesystem/path.hpp>
#include <memory>
namespace blobstore { namespace blobstore {
namespace ondisk { namespace ondisk {
@ -14,6 +15,7 @@ namespace ondisk {
class Data { class Data {
public: public:
Data(size_t size); Data(size_t size);
Data(Data &&rhs); // move constructor
virtual ~Data(); virtual ~Data();
void *data(); void *data();
@ -21,12 +23,18 @@ public:
size_t size() const; size_t size() const;
void FillWithZeroes();
void StoreToFile(const boost::filesystem::path &filepath) const; void StoreToFile(const boost::filesystem::path &filepath) const;
static std::unique_ptr<Data> LoadFromFile(const boost::filesystem::path &filepath);
private: private:
size_t _size; size_t _size;
void *_data; void *_data;
static size_t _getStreamSize(std::istream &stream);
void _readFromStream(std::istream &stream);
DISALLOW_COPY_AND_ASSIGN(Data); DISALLOW_COPY_AND_ASSIGN(Data);
}; };

View File

@ -21,7 +21,11 @@ namespace blobstore {
namespace ondisk { namespace ondisk {
OnDiskBlob::OnDiskBlob(const bf::path &filepath, size_t size) OnDiskBlob::OnDiskBlob(const bf::path &filepath, size_t size)
: _filepath(filepath), _size(size), _data(size) { : _filepath(filepath), _data(size) {
}
OnDiskBlob::OnDiskBlob(const bf::path &filepath, Data &&data)
: _filepath(filepath), _data(std::move(data)) {
} }
OnDiskBlob::~OnDiskBlob() { OnDiskBlob::~OnDiskBlob() {
@ -36,41 +40,21 @@ const void *OnDiskBlob::data() const {
} }
size_t OnDiskBlob::size() const { size_t OnDiskBlob::size() const {
return _size; return _data.size();
} }
unique_ptr<OnDiskBlob> OnDiskBlob::LoadFromDisk(const bf::path &filepath) { unique_ptr<OnDiskBlob> OnDiskBlob::LoadFromDisk(const bf::path &filepath) {
ifstream file(filepath.c_str(), ios::binary); auto data = Data::LoadFromFile(filepath);
size_t size = _getStreamSize(file);
auto blob = make_unique<OnDiskBlob>(filepath, size); return unique_ptr<OnDiskBlob>(new OnDiskBlob(filepath, std::move(*data.get())));
blob->_loadDataFromStream(file);
return blob;
}
size_t OnDiskBlob::_getStreamSize(istream &stream) {
auto current_pos = stream.tellg();
//Retrieve length
stream.seekg(0, stream.end);
auto endpos = stream.tellg();
//Restore old position
stream.seekg(current_pos, stream.beg);
return endpos - current_pos;
}
void OnDiskBlob::_loadDataFromStream(istream &stream) {
stream.read((char*)_data.data(), _size);
} }
unique_ptr<OnDiskBlob> OnDiskBlob::CreateOnDisk(const bf::path &filepath, size_t size) { unique_ptr<OnDiskBlob> OnDiskBlob::CreateOnDisk(const bf::path &filepath, size_t size) {
_assertFileDoesntExist(filepath); _assertFileDoesntExist(filepath);
auto blob = make_unique<OnDiskBlob>(filepath, size); auto blob = unique_ptr<OnDiskBlob>(new OnDiskBlob(filepath, size));
blob->_fillDataWithZeroes(); blob->_fillDataWithZeroes();
blob->_storeToDisk(); blob->_storeToDisk();
return std::move(blob); return blob;
} }
void OnDiskBlob::_assertFileDoesntExist(const bf::path &filepath) { void OnDiskBlob::_assertFileDoesntExist(const bf::path &filepath) {
@ -80,7 +64,7 @@ void OnDiskBlob::_assertFileDoesntExist(const bf::path &filepath) {
} }
void OnDiskBlob::_fillDataWithZeroes() { void OnDiskBlob::_fillDataWithZeroes() {
std::memset(_data.data(), 0, _size); _data.FillWithZeroes();
} }
void OnDiskBlob::_storeToDisk() const { void OnDiskBlob::_storeToDisk() const {

View File

@ -14,7 +14,6 @@ class OnDiskBlobStore;
class OnDiskBlob: public Blob { class OnDiskBlob: public Blob {
public: public:
OnDiskBlob(const boost::filesystem::path &filepath, size_t size);
virtual ~OnDiskBlob(); virtual ~OnDiskBlob();
static std::unique_ptr<OnDiskBlob> LoadFromDisk(const boost::filesystem::path &filepath); static std::unique_ptr<OnDiskBlob> LoadFromDisk(const boost::filesystem::path &filepath);
@ -27,13 +26,12 @@ public:
private: private:
const boost::filesystem::path _filepath; const boost::filesystem::path _filepath;
size_t _size;
Data _data; Data _data;
OnDiskBlob(const boost::filesystem::path &filepath, size_t size);
OnDiskBlob(const boost::filesystem::path &filepath, Data &&data);
static void _assertFileDoesntExist(const boost::filesystem::path &filepath); static void _assertFileDoesntExist(const boost::filesystem::path &filepath);
static size_t _getStreamSize(std::istream &stream);
void _loadDataFromStream(std::istream &stream);
void _storeDataToStream(std::ostream &stream) const;
void _fillDataWithZeroes(); void _fillDataWithZeroes();
void _storeToDisk() const; void _storeToDisk() const;
}; };