A platform for high-performance distributed tool and library development written in C++. It can be deployed in two different cluster modes: standalone or distributed. API for v0.5.0, released on June 13, 2018.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
DefaultDatabase.cc
Go to the documentation of this file.
1 /*****************************************************************************
2  * *
3  * Copyright 2018 Rice University *
4  * *
5  * Licensed under the Apache License, Version 2.0 (the "License"); *
6  * you may not use this file except in compliance with the License. *
7  * You may obtain a copy of the License at *
8  * *
9  * http://www.apache.org/licenses/LICENSE-2.0 *
10  * *
11  * Unless required by applicable law or agreed to in writing, software *
12  * distributed under the License is distributed on an "AS IS" BASIS, *
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
14  * See the License for the specific language governing permissions and *
15  * limitations under the License. *
16  * *
17  *****************************************************************************/
18 
19 
20 #ifndef DEFAULT_DATABASE_CC
21 #define DEFAULT_DATABASE_CC
22 
23 #include "DefaultDatabase.h"
24 #include <map>
25 #include <memory>
26 
27 using namespace std;
28 
29 // create a new DefaultDatabase instance
31  DatabaseID dbId,
32  string dbName,
33  ConfigurationPtr conf,
34  pdb::PDBLoggerPtr logger,
35  SharedMemPtr shm,
36  string metaDBPath,
37  vector<string>* dataDBPaths,
38  PageCachePtr cache,
39  PageCircularBufferPtr flushBuffer) {
40  this->nodeId = nodeId;
41  this->dbId = dbId;
42  this->dbName = dbName;
43  this->conf = conf;
44  this->logger = logger;
45  this->shm = shm;
46  this->metaDBPath = metaDBPath;
47  this->dataDBPaths = dataDBPaths;
48  unsigned int i;
49  if (this->metaDBPath.compare("") != 0) {
50  this->conf->createDir(this->metaDBPath);
51  }
52  for (i = 0; i < this->dataDBPaths->size(); i++) {
53  this->conf->createDir(this->dataDBPaths->at(i));
54  }
55  this->types = new map<UserTypeID, TypePtr>();
56  pthread_mutex_init(&this->typeOpLock, nullptr);
57  this->cache = cache;
58  this->flushBuffer = flushBuffer;
59 }
60 
61 // destructor
63  if (this->types != nullptr) {
64  delete this->types;
65  }
66  pthread_mutex_destroy(&this->typeOpLock);
67 }
68 
69 
70 // encode type path
71 string DefaultDatabase::encodeTypePath(string dbPath, UserTypeID typeId, string typeName) {
72  char buffer[500];
73  sprintf(buffer, "%s/%d_%s", dbPath.c_str(), typeId, typeName.c_str());
74  return string(buffer);
75 }
76 
77 // add a new type
78 bool DefaultDatabase::addType(string name, UserTypeID id) {
79  if (this->types->find(id) != this->types->end()) {
80  this->logger->writeLn("DefaultDatabase: type exists.");
81  return false;
82  }
83  string metaTypePath = encodeTypePath(this->metaDBPath, id, name);
84  vector<string>* dataTypePaths = new vector<string>();
85  unsigned int i;
86  for (i = 0; i < this->dataDBPaths->size(); i++) {
87  string dataTypePath = encodeTypePath(this->dataDBPaths->at(i), id, name);
88  dataTypePaths->push_back(dataTypePath);
89  }
90  TypePtr type = make_shared<UserType>(this->nodeId,
91  this->dbId,
92  id,
93  name,
94  this->conf,
95  this->logger,
96  this->shm,
97  metaTypePath,
98  dataTypePaths,
99  this->cache,
100  this->flushBuffer);
101  this->addType(type);
102  return true;
103 }
104 
105 // add a new type
107  UserTypeID typeId = type->getId();
108  if (this->types->find(typeId) != this->types->end()) {
109  this->logger->writeLn("DefaultDatabase: type exists.");
110  return false;
111  }
112  pthread_mutex_lock(&this->typeOpLock);
113  types->insert(pair<UserTypeID, TypePtr>(typeId, type));
114  pthread_mutex_unlock(&this->typeOpLock);
115  return true;
116 }
117 
118 // remove a type and associated disk files
120  this->logger->writeInt(typeId);
121  map<UserTypeID, TypePtr>::iterator it = types->find(typeId);
122  if (it != types->end()) {
123  pthread_mutex_lock(&this->typeOpLock);
124  this->clearType(typeId, it->second->getName());
125  this->types->erase(it); // will erase invoke destructor of element???
126  pthread_mutex_unlock(&this->typeOpLock);
127  return true;
128  } else {
129  this->logger->writeLn("DefaultDatabase: Type doesn't exist:");
130  this->logger->writeInt(typeId);
131  return false;
132  }
133 }
134 
135 // clear type data and associated disk files for removal
136 void DefaultDatabase::clearType(UserTypeID typeId, string typeName) {
137  unsigned int i;
138  remove(this->metaDBPath.c_str());
139  string typePath;
140  for (i = 0; i < this->dataDBPaths->size(); i++) {
141  typePath = encodeTypePath(this->dataDBPaths->at(i), typeId, typeName);
142  boost::filesystem::remove_all(typePath.c_str());
143  }
144 }
145 
146 // returns a type specified
148  map<UserTypeID, TypePtr>::iterator it = this->types->find(typeId);
149  if (it != this->types->end()) {
150  return it->second;
151  }
152  this->logger->writeLn("DefaultDatabase: type doesn't exist");
153  return nullptr;
154 }
155 
156 // flush data from memory to disk files
157 // flush is now fully managed by PageCache, so do nothing here
159 }
160 // returns database id
162  return this->dbId;
163 }
164 
165 // returns database name
167  return this->dbName;
168 }
169 
170 using namespace boost::filesystem;
171 
177  if (exists(metaDBDir)) {
178  if (is_directory(metaDBDir)) {
179  vector<path> typeDirs;
180  copy(directory_iterator(metaDBDir), directory_iterator(), back_inserter(typeDirs));
181  vector<path>::iterator iter;
182  std::string path;
183  std::string dirName;
184  std::string name;
185  UserTypeID typeId;
186  for (iter = typeDirs.begin(); iter != typeDirs.end(); iter++) {
187  if (is_directory(*iter)) {
188  // find a type
189  path = std::string(iter->c_str());
190  dirName = path.substr(path.find_last_of('/') + 1, path.length() - 1);
191  // parse type name
192  name = dirName.substr(dirName.find('_') + 1, dirName.length() - 1);
193  // parse type id
194  typeId = stoul(dirName.substr(0, dirName.find('_')));
195 
196  // load existing types
197  this->addTypeByPartitionedFiles(name, typeId, path);
198  }
199  }
200  } else {
201  this->logger->writeLn("DefaultDatabase: dbDir doesn't exist:");
202  this->logger->writeLn(metaDBDir.c_str());
203  return false;
204  }
205  } else {
206  return false;
207  }
208  return true;
209 }
210 
215  UserTypeID id,
216  boost::filesystem::path metaTypeDir) {
217  if (this->types->find(id) != this->types->end()) {
218  this->logger->writeLn("DefaultDatabase: type exists.");
219  return;
220  }
221  vector<string>* dataTypePaths = new vector<string>();
222  int numDataPaths = this->dataDBPaths->size();
223  int i = 0;
224  string dataTypePath;
225  for (i = 0; i < numDataPaths; i++) {
226  dataTypePath = this->encodeTypePath(dataDBPaths->at(i), id, name);
227  dataTypePaths->push_back(dataTypePath);
228  }
229 
230  TypePtr type = make_shared<UserType>(this->nodeId,
231  this->dbId,
232  id,
233  name,
234  this->conf,
235  this->logger,
236  this->shm,
237  string(metaTypeDir.c_str()),
238  dataTypePaths,
239  this->cache,
240  this->flushBuffer);
241  if (type == nullptr) {
242  this->logger->error("Fatal Error: DefaultDatabase: Out of Memory.");
243  exit(1);
244  }
245  type->initializeFromMetaTypeDir(metaTypeDir);
246  this->addType(type);
247 }
248 
254  if (exists(dbDir)) {
255  if (is_directory(dbDir)) {
256  vector<path> typeDirs;
257  copy(directory_iterator(dbDir), directory_iterator(), back_inserter(typeDirs));
258  vector<path>::iterator iter;
259  std::string path;
260  std::string dirName;
261  std::string name;
262  UserTypeID typeId;
263  for (iter = typeDirs.begin(); iter != typeDirs.end(); iter++) {
264  if (is_directory(*iter)) {
265  this->logger->writeLn("DefaultDatabase: find a type at path:");
266  this->logger->writeLn(iter->c_str());
267  path = std::string(iter->c_str());
268  dirName = path.substr(path.find_last_of('/') + 1, path.length() - 1);
269  name = dirName.substr(dirName.find('_') + 1, dirName.length() - 1);
270  this->logger->writeLn("DefaultDatabase: typeName:");
271  this->logger->writeLn(name.c_str());
272  typeId = stoul(dirName.substr(0, dirName.find('_')));
273  this->logger->writeLn("DefaultDatabase: typeId:");
274  this->logger->writeInt(typeId);
275  cout << "DefaultDatabase: detect type at path: " << path << "\n";
276  cout << "Type name: " << name << "\n";
277  cout << "Type ID:" << typeId << "\n";
278  this->addTypeBySequenceFiles(name, typeId, path);
279  }
280  }
281  } else {
282  this->logger->writeLn("DefaultDatabase: dbDir doesn't exist:");
283  this->logger->writeLn(dbDir.c_str());
284  return false;
285  }
286  } else {
287  return false;
288  }
289  return true;
290 }
291 
296  UserTypeID id,
297  boost::filesystem::path typeDir) {
298  if (this->types->find(id) != this->types->end()) {
299  this->logger->writeLn("DefaultDatabase: type exists.");
300  return;
301  }
302  vector<string>* dataTypePaths = new vector<string>();
303  dataTypePaths->push_back(std::string(typeDir.c_str()));
304  TypePtr type = make_shared<UserType>(this->nodeId,
305  this->dbId,
306  id,
307  name,
308  this->conf,
309  this->logger,
310  this->shm,
311  "",
312  dataTypePaths,
313  this->cache,
314  this->flushBuffer);
315  if (type == nullptr) {
316  this->logger->writeLn("Fatal Error: DefaultDatabase: Out of Memory.");
317  exit(1);
318  }
319  type->initializeFromTypeDir(typeDir);
320  this->addType(type);
321 }
322 
326 map<UserTypeID, TypePtr>* DefaultDatabase::getTypes() {
327  return this->types;
328 }
329 
330 
331 #endif
bool addType(TypePtr type)
shared_ptr< UserType > TypePtr
Definition: UserType.h:41
shared_ptr< PageCache > PageCachePtr
Definition: PageCache.h:39
bool initializeFromMetaDBDir(boost::filesystem::path metaDBDir)
bool removeType(UserTypeID typeID)
void addTypeBySequenceFiles(string name, UserTypeID id, boost::filesystem::path typeDir)
unsigned int NodeID
Definition: DataTypes.h:27
DatabaseID getDatabaseID()
shared_ptr< SharedMem > SharedMemPtr
Definition: SharedMem.h:32
void clearType(UserTypeID typeId, string typeName)
unsigned int DatabaseID
Definition: DataTypes.h:29
string encodeTypePath(string dbPath, UserTypeID typeId, string typeName)
TypePtr getType(UserTypeID typeId)
DefaultDatabase(NodeID nodeId, DatabaseID dbId, string dbName, ConfigurationPtr conf, pdb::PDBLoggerPtr logger, SharedMemPtr shm, string metaDBPath, vector< string > *dataDBPaths, PageCachePtr cache, PageCircularBufferPtr flushBuffer)
shared_ptr< Configuration > ConfigurationPtr
Definition: Configuration.h:89
bool initializeFromDBDir(boost::filesystem::path dbDir)
map< UserTypeID, TypePtr > * getTypes()
std::shared_ptr< PDBLogger > PDBLoggerPtr
Definition: PDBLogger.h:40
string getDatabaseName()
shared_ptr< PageCircularBuffer > PageCircularBufferPtr
unsigned int UserTypeID
Definition: DataTypes.h:25
void addTypeByPartitionedFiles(string name, UserTypeID id, boost::filesystem::path metaTypeDir)