IBR-DTNSuite
0.8
|
00001 /* 00002 * DataStorage.h 00003 * 00004 * Created on: 22.11.2010 00005 * Author: morgenro 00006 */ 00007 00008 #include <iostream> 00009 #include <fstream> 00010 #include <string> 00011 #include <ibrcommon/data/File.h> 00012 #include <ibrcommon/thread/Mutex.h> 00013 #include <ibrcommon/thread/MutexLock.h> 00014 #include <ibrcommon/thread/Queue.h> 00015 #include <ibrcommon/thread/Thread.h> 00016 #include <ibrcommon/thread/Semaphore.h> 00017 00018 #ifndef DATASTORAGE_H_ 00019 #define DATASTORAGE_H_ 00020 00021 namespace dtn 00022 { 00023 namespace storage 00024 { 00025 class DataStorage : public ibrcommon::JoinableThread 00026 { 00027 public: 00028 class DataNotAvailableException : public ibrcommon::Exception 00029 { 00030 public: 00031 DataNotAvailableException(string what = "Requested data is not available.") throw() : Exception(what) 00032 { }; 00033 }; 00034 00035 class Container 00036 { 00037 public: 00038 virtual ~Container() = 0; 00039 virtual std::string getKey() const = 0; 00040 virtual std::ostream& serialize(std::ostream &stream) = 0; 00041 }; 00042 00043 class Hash 00044 { 00045 public: 00046 Hash(); 00047 Hash(const std::string &key); 00048 Hash(const DataStorage::Container &container); 00049 Hash(const ibrcommon::File &file); 00050 virtual ~Hash(); 00051 00052 bool operator==(const Hash &other) const; 00053 bool operator<(const Hash &other) const; 00054 00055 std::string value; 00056 00057 private: 00058 static std::string hash(const std::string &value); 00059 }; 00060 00061 class istream : public ibrcommon::File 00062 { 00063 public: 00064 istream(ibrcommon::Mutex &mutex, const ibrcommon::File &file); 00065 virtual ~istream(); 00066 std::istream& operator*(); 00067 00068 private: 00069 std::ifstream *_stream; 00070 ibrcommon::Mutex &_lock; 00071 }; 00072 00073 class Callback 00074 { 00075 public: 00076 virtual void eventDataStorageStored(const Hash &hash) = 0; 00077 virtual void eventDataStorageStoreFailed(const Hash &hash, const ibrcommon::Exception&) = 0; 00078 virtual void eventDataStorageRemoved(const Hash &hash) = 0; 00079 virtual void eventDataStorageRemoveFailed(const Hash &hash, const ibrcommon::Exception&) = 0; 00080 virtual void iterateDataStorage(const Hash &hash, DataStorage::istream &stream) = 0; 00081 }; 00082 00083 DataStorage(Callback &callback, const ibrcommon::File &path, size_t write_buffer = 0, bool initialize = false); 00084 virtual ~DataStorage(); 00085 00086 const Hash store(Container *data); 00087 void store(const Hash &hash, Container *data); 00088 00089 DataStorage::istream retrieve(const Hash &hash) throw (DataNotAvailableException); 00090 void remove(const Hash &hash); 00091 00092 void iterateAll(); 00093 00094 protected: 00095 void run(); 00096 void __cancellation(); 00097 00098 private: 00099 class Task 00100 { 00101 public: 00102 virtual ~Task() = 0; 00103 }; 00104 00105 class StoreDataTask : public Task 00106 { 00107 public: 00108 StoreDataTask(const Hash &h, Container *c); 00109 virtual ~StoreDataTask(); 00110 00111 const Hash hash; 00112 Container *container; 00113 }; 00114 00115 class RemoveDataTask : public Task 00116 { 00117 public: 00118 RemoveDataTask(const Hash &h); 00119 virtual ~RemoveDataTask(); 00120 00121 const Hash hash; 00122 }; 00123 00124 Callback &_callback; 00125 ibrcommon::File _path; 00126 ibrcommon::Queue< Task* > _tasks; 00127 ibrcommon::Semaphore _store_sem; 00128 bool _store_limited; 00129 00130 ibrcommon::Mutex _global_mutex; 00131 }; 00132 } 00133 } 00134 00135 #endif /* DATASTORAGE_H_ */