voxelTerrain
 All Classes Functions Variables Typedefs Enumerations Pages
database.hpp
1 #ifndef BLUB_PROCEDURAL_VOXEL_SIMPLE_CONTAINER_DATABASE_HPP
2 #define BLUB_PROCEDURAL_VOXEL_SIMPLE_CONTAINER_DATABASE_HPP
3 
4 //#ifdef BLUB_BUILD_DATABASE
5 
6 // #include "blub/log/global.hpp"
7 #include "blub/core/base64.hpp"
8 #include "blub/core/byteArray.hpp"
9 #include "blub/core/vector.hpp"
10 #include "blub/database/connection.hpp"
11 #include "blub/database/functions.hpp"
12 #include "blub/procedural/log/global.hpp"
13 #include "blub/procedural/voxel/simple/container/inMemory.hpp"
14 #include "blub/procedural/voxel/simple/container/utils/tile.hpp"
15 #include "blub/serialization/format/binary/input.hpp"
16 #include "blub/serialization/format/binary/output.hpp"
17 
18 #include <functional>
19 #include <boost/interprocess/streams/vectorstream.hpp>
20 
21 
22 namespace blub
23 {
24 namespace procedural
25 {
26 namespace voxel
27 {
28 namespace simple
29 {
30 namespace container
31 {
32 
33 
34 template <class voxelType>
35 class database : public inMemory<voxelType>
36 {
37 public:
38  typedef inMemory<voxelType> t_base;
39  typedef std::function<byteArray (const byteArray&)> t_funcCompress;
40 
41  database(blub::async::dispatcher &worker, blub::database::connection& dbConn)
42  : t_base(worker)
43  , m_databaseConnection(dbConn)
44  , m_loading(false)
45  , m_writeToDatabase(true)
46  {
47 #ifdef BLUB_LOG_VOXEL
48  blub::BOUT("database::database()");
49 #endif
50 
51  }
52  ~database()
53  {
54  #ifdef BLUB_LOG_VOXEL
55  blub::BOUT("database::~database()");
56  #endif
57  }
58 
59  void loadTS()
60  {
61  t_base::m_master.dispatch(boost::bind(&database::loadMaster, this));
62  }
63 
64  void loadMaster()
65  {
66  m_loading = true;
67  uint32 numData;
68  m_databaseConnection << "select count(*) from voxel_tiles"
69  , blub::database::into(numData);
70  if (numData == 0)
71  {
72  BLUB_PROCEDURAL_LOG_WARNING() << "numData == 0";
73  return;
74  }
75  std::vector<int32> xList(numData);
76  std::vector<int32> yList(numData);
77  std::vector<int32> zList(numData);
78  m_databaseConnection << "select x, y, z from voxel_tiles"
79  , soci::into(xList), soci::into(yList), soci::into(zList);
80  BASSERT(xList.size() == yList.size());
81  BASSERT(xList.size() == zList.size());
83  for (uint32 ind = 0; ind < xList.size(); ++ind)
84  {
85  const vector3int32 id(xList[ind], yList[ind], zList[ind]);
86  typename t_base::t_utilsTile tile(getTileHolderFromDatabaseMaster(id));
87  t_base::setTileMaster(id, tile);
88  }
89  m_loading = false;
91  }
92 
93  byteArray getTileHolderDatabaseMaster(const blub::vector3int32& id) const
94  {
95  soci::indicator indicator = soci::i_null;
96  std::string selectData;
97  m_databaseConnection << "select data from voxel_tiles where x = :x and y = :y and z = :z"
98  , soci::into(selectData, indicator), blub::database::use(id.x), blub::database::use(id.y), blub::database::use(id.z);
99  if (indicator == soci::i_ok)
100  {
101  byteArray decompressed(base64::decode(selectData));
102  if (m_funcDecompress)
103  {
104  decompressed = m_funcDecompress(decompressed);
105  }
106 
107  return decompressed;
108  }
109  return byteArray();
110  }
111 
112  typename t_base::t_utilsTile getTileHolderFromDatabaseMaster(const blub::vector3int32& id) const
113  {
114  typename t_base::t_utilsTile result;
115 
116  const byteArray &strToCast(getTileHolderDatabaseMaster(id));
117 
118  if (!strToCast.empty())
119  {
120  boost::interprocess::basic_ivectorstream<byteArray> dataContainer(strToCast);
121 // std::istringstream dataContainer(std::string(strToCast.data(), strToCast.size()));
122  {
123  blub::serialization::format::binary::input format(dataContainer);
124  format >> result.state;
125  if (result.state == utils::tileState::partitial)
126  {
127  result.data = t_base::createTileFull(false);
128 
129  format >> (*result.data.data());
130  }
131  }
132  }
133 
134  return result;
135  }
136 
137 
138  void setWriteToDatabase(const bool& en)
139  {
140  m_writeToDatabase = en;
141  }
142  void setCompressionCallback(const t_funcCompress& compress, const t_funcCompress& decompress)
143  {
144  m_funcCompress = compress;
145  m_funcDecompress = decompress;
146  }
147 
148 
149 protected:
150  virtual void setTileDatabaseMaster(const vector3int32 &id, const blub::byteArray &toSet, const bool &insert, const bool &update, const bool &remove)
151  {
152 #ifdef BLUB_DEBUG
153  if (remove)
154  {
155  BASSERT(!update);
156  BASSERT(!insert);
157  }
158  if (insert)
159  {
160  BASSERT(!update);
161  BASSERT(!remove);
162  }
163  if (update)
164  {
165  BASSERT(!insert);
166  BASSERT(!remove);
167  }
168 #endif
169 
170  const byteArray *work(&toSet);
171  byteArray toSetCompressed;
172  if (m_funcCompress)
173  {
174  toSetCompressed = m_funcCompress(toSet);
175  work = &toSetCompressed;
176  }
177  const blub::string toSetBase64(base64::encode(*work));
178 
179 
180  if (insert)
181  {
182  m_databaseConnection << "insert into voxel_tiles(x, y, z, data) values(:x, :y, :z, :data)"
183  , blub::database::use(id.x), blub::database::use(id.y), blub::database::use(id.z)
184  , blub::database::use(toSetBase64);
185  return;
186  }
187  if (remove)
188  {
189  m_databaseConnection << "delete data from voxel_tiles where x = :x and y = :y and z = :z"
190  , blub::database::use(id.x), blub::database::use(id.y), blub::database::use(id.z);
191  return;
192  }
193  if (update)
194  {
195  m_databaseConnection << "update voxel_tiles set data = :data where x = :x and y = :y and z = :z"
196  , blub::database::use(toSetBase64), blub::database::use(id.x), blub::database::use(id.y), blub::database::use(id.z);
197  return;
198  }
199  }
200 
202  const typename t_base::t_utilsTile &oldOne,
203  const typename t_base::t_utilsTile &toSet) override
204  {
205  t_base::setTileToContainerMaster(id, oldOne, toSet);
206 
207  if (m_loading || !m_writeToDatabase)
208  {
209  return;
210  }
211  std::stringstream dataContainer;
212  {
213  blub::serialization::format::binary::output format(dataContainer);
214  format << toSet.state;
215  if (toSet.state == utils::tileState::partitial)
216  {
217  BASSERT(!toSet.data.isNull());
218  format << *toSet.data.data();
219  }
220  }
221  const blub::byteArray strCasted(dataContainer.str());
222 
223  setTileDatabaseMaster(id, strCasted,
224  oldOne.state == utils::tileState::empty,
225  (toSet.state != utils::tileState::empty) && (oldOne.state != utils::tileState::empty),
226  toSet.state == utils::tileState::empty);
227  }
228 
229 
230 protected:
231  blub::database::connection &m_databaseConnection;
232  bool m_loading;
233  bool m_writeToDatabase;
234  t_funcCompress m_funcCompress;
235  t_funcCompress m_funcDecompress;
236 
237 private:
238 
239 };
240 
241 
242 }
243 }
244 }
245 }
246 }
247 
248 //#endif // BLUB_BUILD_DATABASE
249 
250 #endif // BLUB_PROCEDURAL_VOXEL_SIMPLE_CONTAINER_DATABASE_HPP
void setTileToContainerMaster(const typename t_base::t_tileId id, const typename t_base::t_utilsTile &oldOne, const typename t_base::t_utilsTile &toSet) override
setTileToContainerMaster replaces a tile. Call method by one thread at a time. Write-lock class befor...
Definition: database.hpp:201
static t_tilePtr createTileFull(const bool &full)
createTileFull creates a tile in which all voxel are maximum or minimum.
Definition: base.hpp:416
void lockForEditMaster() override
Definition: base.hpp:193
void unlockForEditMaster() override
Definition: base.hpp:176
Definition: portable_binary_oarchive.hpp:63
Definition: string.hpp:22
Definition: dispatcher.hpp:29
Definition: byteArray.hpp:17
void setTileMaster(const blub::vector3int32 &id, const typename t_base::t_utilsTile &toSet) override
setTileMaster sets a tile to an id. Call by one thread at a time.
Definition: inMemory.hpp:125
Definition: portable_binary_iarchive.hpp:68
Definition: deadlineTimer.hpp:10
blub::async::strand m_master
m_master The master synchronises jobs for the worker-thread and writes to class member. The master calls all methods which end with *Master.
Definition: base.hpp:143
virtual void setTileToContainerMaster(const typename t_base::t_tileId id, const typename t_base::t_utilsTile &oldOne, const typename t_base::t_utilsTile &toSet)
setTileToContainerMaster replaces a tile. Call method by one thread at a time. Write-lock class befor...
Definition: inMemory.hpp:112