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
VTableMap.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 #include "Object.h"
20 #include "Nothing.h"
21 
22 #ifndef PDBCATALOG_VTABLEMAP_C_
23 #define PDBCATALOG_VTABLEMAP_C_
24 
25 /*
26  * VTableMap.cc
27  */
28 
29 // This header is auto-generated by SConstruct... it includes all of the header files
30 // in BuiltInPDBObjects/headers
31 
32 #include <dlfcn.h>
33 #include "PDBDebug.h"
34 #include "LockGuard.h"
35 #include <unistd.h>
36 #include "PDBLogger.h"
37 #include <cctype>
38 
39 namespace pdb {
40 
41 inline int16_t VTableMap::lookupBuiltInType(std::string objectTypeName) {
42  if (theVTable->objectTypeNamesList.count(objectTypeName) != 0)
43  if (theVTable->objectTypeNamesList[objectTypeName] >= 0 &&
44  theVTable->objectTypeNamesList[objectTypeName] <= 8191)
45  return theVTable->objectTypeNamesList[objectTypeName];
46 
47  // otherwise, return -1 to signify that this was not a built-in type
48  return -1;
49 }
50 
51 inline std::string VTableMap::lookupBuiltInType(int16_t objectType) {
52 
53  // loop through every type in the mape
54  for (auto& a : theVTable->objectTypeNamesList) {
55  if (a.second == objectType)
56  return a.first;
57  }
58 
59  // otherwise, return "" to signify that this was not a built-in type
60  return "";
61 }
62 
63 // returns the number of registered built-in objects
65  int count = 0;
66  for (unsigned int i = 0; i < theVTable->allVTables.size(); i++) {
67  if (theVTable->allVTables[i] != nullptr) {
68  count = count + 1;
69  }
70  }
71  return count;
72 }
73 
75  for (unsigned int i = 0; i < theVTable->allVTables.size(); i++) {
76  if (theVTable->allVTables[i] != nullptr)
77  PDB_COUT << "vtpr " << i << ": " << theVTable->allVTables[i] << std::endl;
78  }
79 }
80 
82  std::map<std::string, int16_t> iterator;
83 
84  for (auto& iterator : theVTable->objectTypeNamesList) {
85  std::cout << "Type name= " << iterator.first << " | TypeId= " << iterator.second
86  << std::endl;
87  }
88 }
89 
90 inline int16_t VTableMap::getIDByName(std::string objectTypeName, bool withLock) {
91  // PDB_COUT << "getIDByName for " << objectTypeName << std :: endl;
92  // one important issue is that we might need to lookup soething nasty like:
93  //
94  // pdb::PairArray<pdb::Handle<pdb::String>,pdb::Handle<pdb::Employee>>
95  //
96  // this needs to be normalized to:
97  //
98  // pdb::PairArray<<pdb::Nothing>,<pdb::Nothing>?
99  //
100  // basically, we have a stack that pushes and pops the depth of the template by counting
101  // instances of '>' and '<'
102  // Any time that we see a "," at depth 1, it means we've hit an additional template arguement,
103  // and so we add
104  // a "<pdb::Nothing>" to the replacement string
105  std::string replacementString("");
106  std::string prefix("");
107  bool isTemplate = false;
108  int depth = 0;
109  int length = objectTypeName.size();
110  for (unsigned int loc = 0; loc < length; loc++) {
111  if (objectTypeName[loc] == '<') {
112  depth++;
113  if (depth == 1) {
114  isTemplate = true;
115  prefix = objectTypeName.substr(0, loc);
116  replacementString = std::string("pdb::Nothing");
117  }
118  } else if (objectTypeName[loc] == '>') {
119  depth--;
120  } else if (objectTypeName[loc] == ',' && depth == 1) {
121  std::string nextReplacement(",pdb::Nothing");
122  replacementString += nextReplacement;
123  }
124  }
125 
126  // if this was a template, do the normalization
127  if (isTemplate)
128  objectTypeName = prefix + std::string("<") + replacementString + std::string(">");
129 
130  // now, check to make sure that we have seen the given object type before
131  // PDB_COUT << "objectTypeName=" << objectTypeName << std :: endl;
132  if (theVTable->objectTypeNamesList.count(objectTypeName) == 0 &&
133  theVTable->catalog != nullptr) {
134 
135  // make sure no one is modifying the map
136  int16_t identifier;
137  if (withLock == true) {
138  const LockGuard guard{theVTable->myLock};
139  // in this case, we do not have this object type, and we have never looked for it before
140  // so, go to the catalog and ask for it...
141  identifier = lookupTypeNameInCatalog(objectTypeName);
142  // if the identifier is -1, then it means the catalog has never seen this type before
143  // so let the caller know, and remember that we have not seen it
144  if (identifier == -1) {
146  return TYPE_NOT_RECOGNIZED;
147  // otherwise, return the ID
148  } else {
149  theVTable->objectTypeNamesList[objectTypeName] = identifier;
150  return identifier;
151  }
152  } else {
153  identifier = lookupTypeNameInCatalog(objectTypeName);
154  // if the identifier is -1, then it means the catalog has never seen this type before
155  // so let the caller know, and remember that we have not seen it
156  if (identifier == -1) {
158  return TYPE_NOT_RECOGNIZED;
159  // otherwise, return the ID
160  } else {
161  theVTable->objectTypeNamesList[objectTypeName] = identifier;
162  return identifier;
163  }
164  }
165  } else if (theVTable->objectTypeNamesList.count(objectTypeName) == 0) {
166  // we don't know this type, and we have no catalog client
168  // PDB_COUT << "not builtin and no catalog connection, typeId for " << objectTypeName << "
169  // is " << TYPE_NOT_RECOGNIZED << std :: endl;
170  return TYPE_NOT_RECOGNIZED;
171  } else {
172  // in the easy case, we have seen it before, so just return the typeID
173  int16_t identifier = theVTable->objectTypeNamesList[objectTypeName];
174  // PDB_COUT << "builtin, typeId for " << objectTypeName << " is " << identifier << std ::
175  // endl;
176  return identifier;
177  }
178 }
179 
181  // std :: stringstream ss;
182  // ss << &(theVTable->myLock);
183  // std :: cout << "to get lock at " << ss.str() << "in setCatalogClient" << std :: endl;
184  // pthread_mutex_lock(&theVTable->myLock);
185  const LockGuard guard{theVTable->myLock};
186  // std :: cout << "got lock at " << ss.str() << " in setCatalogClient" << std :: endl;
187 
188  theVTable->catalog = catalogIn;
189  // pthread_mutex_unlock(&theVTable->myLock);
190  // std :: cout << "to release lock at " << ss.str() << " in setCatalogClient" << std :: endl;
191 }
192 
194  // std :: stringstream ss;
195  // ss << &(theVTable->myLock);
196  // std :: cout << "to get lock at " << ss.str() << "in getCatalogClient" << std :: endl;
197  const LockGuard guard{theVTable->myLock};
198  // std :: cout << "got lock at " << ss.str() << " in getCatalogClient" << std :: endl;
199  CatalogClient* client = theVTable->catalog;
200  // std :: cout << "to release lock at " << ss.str() << " in getCatalogClient" << std :: endl;
201  return client;
202 }
203 
204 extern bool inSharedLibrary;
205 
207  // std :: stringstream ss;
208  // ss << &(theVTable->myLock);
209  // std :: cout << "to get lock at " << ss.str() << "in destructor" << std :: endl;
210  // pthread_mutex_lock(&theVTable->myLock);
211  const LockGuard guard{theVTable->myLock};
212  // std :: cout << "got lock at " << ss.str() << " in destructor" << std :: endl;
213 
214  if (!inSharedLibrary)
215  for (void* v : theVTable->so_handles) {
216  int res = dlclose(v);
217  if (res != 0)
218  std::cout << dlerror() << "\n";
219  }
220  theVTable->so_handles.clear();
221  // std :: cout << "released lock at " << ss.str() << " in destructor" << std :: endl;
222 }
223 
224 inline void* VTableMap::getVTablePtr(int16_t objectTypeID) {
225 
226  // it could be a C++ type, we simply return nullptr
227  if (objectTypeID < 0) {
228  return nullptr;
229  }
230 
231  // JIANOTE TODO: we may need lock it, otherwise another thread may change it
232  /*
233  // OK, first, we check to see if we have the v table pointer for this guy...
234  // this is done without a lock, so we can be very fast...
235  */
236  void* returnVal = theVTable->allVTables[objectTypeID];
237  if (returnVal != nullptr) {
238  return returnVal;
239  }
240 
241  const LockGuard guard{theVTable->myLock};
242  // we do not, so get the lock...
243  // std :: stringstream ss;
244  // ss << &(theVTable->myLock);
245  // std :: cout << "to get lock at " << ss.str() << "in getVTablePtr with typeId=" <<
246  // objectTypeID << std :: endl;
247 
248  // std :: cout << "got lock at " << ss.str() << " in getVTablePtr" << std :: endl;
249  // before we go out to the network for the v table pointer, just verify
250  // that another thread has not since gotten it for us
251  returnVal = theVTable->allVTables[objectTypeID];
252 
253  // pthread_mutex_unlock(&theVTable->myLock);
254  if (returnVal != nullptr) {
255  // std :: cout << "to release lock at " << ss.str() << " in getVTablePtr" << std :: endl;
256  return returnVal;
257  } else {
258  // if they have not gotten it for us, then go and get it
259  // PDB_COUT << "VTableMap: to get VTablePtr using Catalog for objectTypeID=" << objectTypeID
260  // << std :: endl;
261  returnVal = getVTablePtrUsingCatalog(objectTypeID);
262  // std :: cout << "to release lock at " << ss.str() << " in getVTablePtr" << std :: endl;
263  return returnVal;
264  }
265 }
266 
267 } /* namespace pdb */
268 
269 #endif
static void listVtableLabels()
Definition: VTableMap.cc:81
std::vector< void * > so_handles
Definition: VTableMap.h:111
std::vector< void * > allVTables
Definition: VTableMap.h:99
bool inSharedLibrary
#define TYPE_NOT_RECOGNIZED
Definition: VTableMap.h:37
static void listVtableEntries()
Definition: VTableMap.cc:74
static int totalBuiltInObjects()
Definition: VTableMap.cc:64
static void * getVTablePtrUsingCatalog(int16_t objectTypeID)
static void * getVTablePtr(int16_t objectTypeID)
Definition: VTableMap.cc:224
static int16_t lookupTypeNameInCatalog(std::string objectTypeName)
CatalogClient * catalog
Definition: VTableMap.h:102
static CatalogClient * getCatalogClient()
Definition: VTableMap.cc:193
#define PDB_COUT
Definition: PDBDebug.h:31
pthread_mutex_t myLock
Definition: VTableMap.h:108
static int16_t getIDByName(std::string objectName, bool withLock=true)
Definition: VTableMap.cc:90
static void setCatalogClient(CatalogClient *catalog)
Definition: VTableMap.cc:180
static int16_t lookupBuiltInType(std::string objectTypeName)
Definition: VTableMap.cc:41
std::map< std::string, int16_t > objectTypeNamesList
Definition: VTableMap.h:96
VTableMap * theVTable