Go to the documentation of this file.00001 #ifndef MEGATREE_STORAGE_H_
00002 #define MEGATREE_STORAGE_H_
00003
00004 #include <assert.h>
00005 #include <megatree/tree_common.h>
00006 #include <boost/filesystem.hpp>
00007 #include <boost/function.hpp>
00008 #include <boost/thread/mutex.hpp>
00009 #include <boost/thread/condition.hpp>
00010 #include <boost/bind.hpp>
00011
00012 namespace megatree {
00013
00014
00015
00016 class Storage
00017 {
00018 public:
00019 virtual ~Storage() {}
00020
00021 virtual void get(const boost::filesystem::path &path, ByteVec &result)
00022 {
00023 std::vector<boost::filesystem::path> p;
00024 std::vector<ByteVec> r;
00025 p.push_back(path);
00026 getBatch(p, r);
00027
00028 if(r.empty())
00029 return;
00030
00031 assert(r.size() == 1);
00032 result.swap(r[0]);
00033 }
00034
00035 virtual void getBatch(const std::vector<boost::filesystem::path> &paths, std::vector<ByteVec> &results)
00036 {
00037 results.resize(paths.size());
00038 unsigned remaining = paths.size();
00039 boost::condition get_condition;
00040
00041
00042 for (size_t i = 0; i < paths.size(); ++i)
00043 getAsync(paths[i], boost::bind(&Storage::getDataCb, this, boost::ref(get_condition), boost::ref(remaining), _1, boost::ref(results[i])));
00044
00045
00046 boost::mutex get_mutex;
00047 boost::mutex::scoped_lock lock(get_mutex);
00048 get_condition.wait(get_mutex);
00049 }
00050
00051 virtual void put(const boost::filesystem::path &path, const ByteVec &data)
00052 {
00053 std::vector<boost::filesystem::path> p;
00054 std::vector<ByteVec> d;
00055 p.push_back(path);
00056 d.push_back(data);
00057 putBatch(p, d);
00058 }
00059
00060 virtual void putBatch(const std::vector<boost::filesystem::path> &paths, std::vector<ByteVec> &data)
00061 {
00062 assert(paths.size() == data.size());
00063 unsigned remaining = paths.size();
00064 boost::condition put_condition;
00065
00066
00067 for (size_t i = 0; i < paths.size(); ++i)
00068 putAsync(paths[i], data[i], boost::bind(&Storage::putDataCb, this, boost::ref(put_condition), boost::ref(remaining)));
00069
00070
00071 boost::mutex put_mutex;
00072 boost::mutex::scoped_lock lock(put_mutex);
00073 put_condition.wait(put_mutex);
00074 }
00075
00076
00077 typedef boost::function<void(const ByteVec&)> GetCallback;
00078 virtual void getAsync(const boost::filesystem::path &path, GetCallback callback) = 0;
00079
00080
00081 typedef boost::function<void(void)> PutCallback;
00082 virtual void putAsync(const boost::filesystem::path &path, const ByteVec &data, PutCallback callback) = 0;
00083
00084 virtual std::string getType() = 0;
00085
00086 protected:
00087 Storage() {}
00088
00089 private:
00090 void getDataCb(boost::condition& get_condition, unsigned& remaining, const ByteVec& data_in, ByteVec& data)
00091 {
00092 remaining--;
00093 data = data_in;
00094
00095 if (remaining == 0)
00096 get_condition.notify_one();
00097 }
00098
00099 void putDataCb(boost::condition& put_condition, unsigned& remaining)
00100 {
00101 remaining--;
00102
00103 if (remaining == 0)
00104 put_condition.notify_one();
00105 }
00106 };
00107
00108
00109 class TempDir
00110 {
00111 protected:
00112 TempDir() {}
00113 public:
00114 virtual ~TempDir() {}
00115 virtual const boost::filesystem::path &getPath() const = 0;
00116 };
00117
00118
00119 }
00120
00121
00122 #endif