OpenASIP 2.2
Loading...
Searching...
No Matches
CachedHDBManager.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file CachedHDBManager.cc
26 *
27 * Implementation of CachedHDBManager class.
28 *
29 * @author Veli-Pekka Jääskeläinen 2007 (vjaaskel-no.spam-cs.tut.fi)
30 * @author Esa Määttä 2007 (esa.maatta-no.spam-tut.fi)
31 * @note rating: red
32 */
33
34#include <iostream>
35
36#include "CachedHDBManager.hh"
37#include "SQLiteConnection.hh"
38#include "MapTools.hh"
39#include "FUArchitecture.hh"
40#include "RFArchitecture.hh"
41#include "FUImplementation.hh"
42#include "RFImplementation.hh"
43#include "CostFunctionPlugin.hh"
44#include "DataObject.hh"
45#include "Conversion.hh"
46#include "Application.hh"
47#include "HDBTypes.hh"
48#include "HDBRegistry.hh"
49
50using namespace HDB;
51
52/**
53 * The Constructor.
54 *
55 * @param hdbFile HDBFile to open.
56 * @throw IOException if an error occured opening the HDB file.
57 */
63
64/**
65 * The Destructor.
66 *
67 * Deletes all cached items.
68 */
77
78
79/**
80 * Returns a CachedHDBManager instance for the given file.
81 *
82 * Only one instance is created per file.
83 *
84 * @param hdbFile Name of the HDB file to open.
85 * @return An instance of HDBManager.
86 * @exception IOException If connection to the DB cannot be established.
87 */
89CachedHDBManager::instance(const std::string& hdbFile) {
91 if (!registry->hasHDB(hdbFile)) {
92 registry->addHDB(new CachedHDBManager(hdbFile));
93 }
94 return registry->hdb(hdbFile);
95}
96
97/**
98 * Creates a new HDB and returns CachedHDBManager instance for accessing it.
99 *
100 * @param file Full path of the new HDB file.
101 * @return CachedHDBManager instance accessing the newly created HDB.
102 * @throw UnreachableStream If the HDB creation was not succesful.
103 */
105CachedHDBManager::createNew(const std::string& file) {
107 return instance(file);
108}
109
110/**
111 * Removes FU architecture from the HDB.
112 *
113 * Removes architecture from the cache and calls base class function to
114 * actually remove the FU architecture.
115 *
116 * @param archID ID of the FU architecture to remove.
117 */
118void
120 // Remove architecture from the cache.
121 std::map<RowID, FUArchitecture*>::iterator iter =
122 fuArchCache_.find(archID);
123
124 if (iter != fuArchCache_.end()) {
125 delete (*iter).second;
126 fuArchCache_.erase(iter);
127 }
128
130}
131
132/**
133 * Removes FU implementation from the HDB.
134 *
135 * Removes implementation from the cache and calls base class function to
136 * actually remove the FU implementation.
137 *
138 * @param id ID of the FU implementation to remove.
139 */
140void
142
143 RowID entryID = fuEntryIDOfImplementation(id);
144
145 // Remove implementation from the cache.
146 std::map<RowID, FUImplementation*>::iterator iter =
147 fuImplCache_.find(entryID);
148
149 if (iter != fuImplCache_.end()) {
150 delete (*iter).second;
151 fuImplCache_.erase(iter);
152 }
153
155}
156
157
158/**
159 * Removes RF architecture from the HDB.
160 *
161 * Removes architecture from the cache and calls base class function to
162 * actually remove the RF architecture.
163 *
164 * @param archID ID of the RF architecture to remove.
165 */
166void
168 // Remove architecture from the cache.
169 std::map<RowID, RFArchitecture*>::iterator iter =
170 rfArchCache_.find(archID);
171
172 if (iter != rfArchCache_.end()) {
173 delete (*iter).second;
174 rfArchCache_.erase(iter);
175 }
176
178}
179
180/**
181 * Removes RF implementation from the HDB.
182 *
183 * Removes implementation from the cache and calls base class function to
184 * actually remove the RF implementation.
185 *
186 * @param id ID of the RF implementation to remove.
187 */
188void
190
191 RowID entryID = rfEntryIDOfImplementation(id);
192
193 // Remove implementation from the cache.
194 std::map<RowID, RFImplementation*>::iterator iter =
195 rfImplCache_.find(entryID);
196
197 if (iter != rfImplCache_.end()) {
198 delete (*iter).second;
199 rfImplCache_.erase(iter);
200 }
201
203}
204
205/**
206 * Returns FU architecture with the given ID.
207 *
208 * First the fu architecture cache is searched for the ID, if the architecture
209 * is found in the cache, a copy of the cached item is returned. If the
210 * architecture was not found in the cache, a DB query is made using the
211 * base class implementation and the item is then added to the cache.
212 *
213 * @param id ID of the fu architecture.
214 * @return FUArchitecture object with the give ID.
215 * @throw KeyNotFound if an architecture with the given id was not found.
216 */
220
221 std::map<RowID, FUArchitecture*>::iterator iter = fuArchCache_.find(id);
222 if (iter != fuArchCache_.end()) {
223 return new FUArchitecture(*(*iter).second);
224 }
225
227 fuArchCache_[id] = arch;
228 return new FUArchitecture(*arch);
229}
230
231/**
232 * Returns RF architecture with the given ID.
233 *
234 * First the RF architecture cache is searched for the ID, if the architecture
235 * is found in the cache, a copy of the cached item is returned. If the
236 * architecture was not found in the cache, a DB query is made using the
237 * base class implementation and the item is then added to the cache.
238 *
239 * @param id ID of the fu architecture.
240 * @return RFArchitecture object with the give ID.
241 * @throw KeyNotFound if an architecture with the given id was not found.
242 */
246
247 std::map<RowID, RFArchitecture*>::iterator iter = rfArchCache_.find(id);
248 if (iter != rfArchCache_.end()) {
249 return new RFArchitecture(*(*iter).second);
250 }
251
253 rfArchCache_[id] = arch;
254 return new RFArchitecture(*arch);
255}
256
257/**
258 * Returns cost estimation data which is not connected to any machine
259 * implementation id.
260 *
261 * This version assumes that there's only one entry with given parameters.
262 * Caches values by plugin name.
263 *
264 * @param valueName Name of the value to fetch.
265 * @param pluginName Name of the cost estimation plugin that owns the data.
266 * @return The data.
267 * @exception KeyNotFound If the HDB does not contain cost estimation
268 * data with the given arguments.
269 */
272 const std::string& valueName, const std::string& pluginName) const {
274
275 std::map<std::string, std::map<std::string, DataObject> >::iterator iter =
276 costEstimationPluginValueCache_.find(pluginName);
277
278 if (iter != costEstimationPluginValueCache_.end()) {
279 std::map<std::string, DataObject>::iterator it =
280 (*iter).second.find(valueName);
281 if (it != (*iter).second.end()) {
282 return (*it).second;
283 } else {
284 DataObject dataObject = HDBManager::costEstimationDataValue(valueName, pluginName);
285 (*iter).second[valueName] = dataObject;
286 return dataObject;
287 }
288 } else {
289 std::map<std::string, DataObject> temp;
290 DataObject dataObject = HDBManager::costEstimationDataValue(valueName, pluginName);
291 temp[valueName] = dataObject;
292 costEstimationPluginValueCache_[pluginName] = temp;
293 return dataObject;
294 }
295}
296
297/**
298 * Cached (invalidates cache) function of
299 * HDBManager::modifyCostFunctionPlugin.
300 *
301 * @param id
302 * @param plugin
303 * @exception InvalidData
304 * @exception KeyNotFound
305 */
306void
308 RowID id, const CostFunctionPlugin& plugin) {
309 // can't say by rowid what plugin is modified
311
313}
314
315/**
316 * Cached (invalidates cache) function of
317 * HDBManager::removeCostFunctionPlugin.
318 *
319 * @param pluginID
320 */
321void
323
324 // can't say by rowid what plugin is removed
326
328}
329
330/**
331 * Cached (invalidates cache) function of
332 * HDBManager::removeFUEntry.
333 *
334 * @param id
335 */
336void
342
343/**
344 * Cached (invalidates cache) function of
345 * HDBManager::removeRFEntry.
346 *
347 * @param id
348 */
349void
355
356/**
357 * Cached (invalidates cache) function of
358 * HDBManager::removeBusEntry.
359 *
360 * @param id
361 */
362void
368
369/**
370 * Cached (invalidates cache) function of
371 * HDBManager::removeSocketEntry.
372 *
373 * @param id
374 */
375void
381
382/**
383 * Cached (invalidates cache) function of
384 * HDBManager::removeCostEstimationData.
385 *
386 * @param id
387 */
388void
394
395/**
396 * Cached (invalidates cache) function of
397 * HDBManager::modifyCostEstimationData.
398 *
399 * @param id
400 * @param data
401 * @exception InvalidData
402 * @exception KeyNotFound
403 */
404void
410
411/**
412 * Returns implementation of a RF with the given index.
413 *
414 * Returns NULL if the RF doesn't have implementation.
415 *
416 * First the RF implementation cache is searched for the ID,
417 * if the implementation is found in the cache, a copy of the cached item is
418 * returned. If the implementation was not found in the cache,
419 * a DB query is made using the base class implementation and the item
420 * is then added to the cache.
421 *
422 *
423 * @param id ID of the RF implementation.
424 * @return RF implementation.
425 */
428
430
431 std::map<RowID, RFImplementation*>::iterator iter = rfImplCache_.find(id);
432 if (iter != rfImplCache_.end()) {
433 return new RFImplementation(*(*iter).second);
434 }
435
437
438 if (impl != NULL) {
439 rfImplCache_[id] = impl;
440 return new RFImplementation(*impl);
441 } else {
442 return NULL;
443 }
444}
445
446/**
447 * Returns implementation of a FU with the given index.
448 *
449 * Returns NULL if the FU doesn't have implementation.
450 *
451 * First the FU implementation cache is searched for the ID,
452 * if the implementation is found in the cache, a copy of the cached item is
453 * returned. If the implementation was not found in the cache,
454 * a DB query is made using the base class implementation and the item
455 * is then added to the cache.
456 *
457 * @param id ID of the FU implementation.
458 * @return FU implementation.
459 */
462 FUArchitecture& architecture, RowID id) const {
463
465
466 std::map<RowID, FUImplementation*>::iterator iter = fuImplCache_.find(id);
467 if (iter != fuImplCache_.end()) {
468 return new FUImplementation(*(*iter).second);
469 }
470
471 FUImplementation* impl =
472 HDBManager::createImplementationOfFU(architecture, id);
473
474 if (impl != NULL) {
475 fuImplCache_[id] = impl;
476 return new FUImplementation(*impl);
477 } else {
478 return NULL;
479 }
480}
481
482
483const FUArchitecture&
485
487
488 std::map<RowID, FUArchitecture*>::iterator iter = fuArchCache_.find(id);
489 if (iter == fuArchCache_.end()) {
491 fuArchCache_[id] = arch;
492 }
493 return *fuArchCache_[id];
494}
495
496
497const RFArchitecture&
499
501
502 std::map<RowID, RFArchitecture*>::iterator iter = rfArchCache_.find(id);
503 if (iter == rfArchCache_.end()) {
505 rfArchCache_[id] = arch;
506 }
507 return *rfArchCache_[id];
508}
509
510
511/**
512 * Wrapper for HDBManager costEstimationDataIDs.
513 *
514 * Compiles and caches queries for HDBManager costEstimationDataIDs function.
515 */
516std::set<RowID>
518 const CostEstimationData& match,
519 bool useCompiledQueries,
520 RelationalDBQueryResult* compiledQuery) const {
521
522 if (!useCompiledQueries) {
524 }
525
526 // query hash (bit vector might be better suited for this)
527 short int queryHash = 0;
528 // calculate query hash only to identify the query
529 HDBManager::createCostEstimatioDataIdsQuery(match, NULL, NULL, &queryHash);
530
531 // check if query already exists
532 std::map<short int,RelationalDBQueryResult*>::iterator it =
533 costEstimationDataIDsQueries_.find(queryHash);
534
535 if (costEstimationDataIDsQueries_.end() != it) {
536 // if query already existed use it
537 return HDBManager::costEstimationDataIDs(match, true, it->second);
538 } else {
539 // else create a new compiledQuery and use it
540 assert(queryHash != 0);
541 std::string query = "";
542 // create bindable query
543 HDBManager::createCostEstimatioDataIdsQuery(match, &query, NULL, NULL, true);
544 compiledQuery = HDBManager::getDBConnection()->query(query, false);
545 costEstimationDataIDsQueries_[queryHash] = compiledQuery;
546 return HDBManager::costEstimationDataIDs(match, true, compiledQuery);
547 }
548}
549
550
551/**
552 * Deletes cached costEstimationDataIDs queries.
553 */
554void
556 std::map<short int,RelationalDBQueryResult*>::iterator it =
558
559 while (it != costEstimationDataIDsQueries_.end()) {
560 delete it->second;
561 it->second = NULL;
562 ++it;
563 }
565}
566
567
568/**
569 * Checks if HDB file is modified. In case it is, invalid cache is cleared.
570 */
571void
573 std::string hdbFile = HDBManager::fileName();
574 std::time_t modTime = FileSystem::lastModificationTime(hdbFile);
575 uintmax_t byteSize = FileSystem::sizeInBytes(hdbFile);
576
577 if (modTime == std::time_t(-1) ||
578 byteSize == static_cast<uintmax_t>(-1)) {
579 // problems accessing the file
580 return;
581 } else if (lastModificationTime_ == modTime &&
582 lastSizeInBytes_ == byteSize) {
583 // no changes
584 return;
585 }
586
587 // delete all cached items
593
594 // set current size and modification time
595 lastModificationTime_ = modTime;
596 lastSizeInBytes_ = byteSize;
597}
#define assert(condition)
int RowID
Type definition of row ID in relational databases.
Definition DBTypes.hh:37
static uintmax_t sizeInBytes(const std::string &filePath)
static std::time_t lastModificationTime(const std::string &filePath)
virtual void removeFUEntry(RowID id) const
virtual void removeRFEntry(RowID id) const
std::map< std::string, std::map< std::string, DataObject > > costEstimationPluginValueCache_
Cost estimation plugin value cache (pluginName/valueName)
const RFArchitecture & rfArchitectureByIDConst(RowID id) const
virtual DataObject costEstimationDataValue(const std::string &valueName, const std::string &pluginName) const
virtual void removeSocketEntry(RowID id) const
static CachedHDBManager & createNew(const std::string &fileName)
virtual void deleteCostEstimationDataIDsQueries() const
virtual void modifyCostEstimationData(RowID id, const CostEstimationData &data)
virtual void modifyCostFunctionPlugin(RowID id, const CostFunctionPlugin &plugin)
virtual FUArchitecture * fuArchitectureByID(RowID id) const
std::map< RowID, RFArchitecture * > rfArchCache_
RF Architecture cache.
std::map< RowID, FUImplementation * > fuImplCache_
FU Implementation cache.
std::map< RowID, RFImplementation * > rfImplCache_
RF Implementation cache.
std::time_t lastModificationTime_
used to detect modifications to the HDB file (which invalidates cache)
std::map< RowID, FUArchitecture * > fuArchCache_
FU Architecture cache.
virtual void removeFUImplementation(RowID id) const
uintmax_t lastSizeInBytes_
used to detect modifications to the HDB file (which invalidates cache)
virtual RFArchitecture * rfArchitectureByID(RowID id) const
virtual FUImplementation * createImplementationOfFU(FUArchitecture &architecture, RowID id) const
virtual void removeRFImplementation(RowID archID) const
std::map< short int, RelationalDBQueryResult * > costEstimationDataIDsQueries_
map of cached (compiled) queries for costEstimatioDataIDs function
static CachedHDBManager & instance(const std::string &hdbFile)
const FUArchitecture & fuArchitectureByIDConst(RowID id) const
virtual std::set< RowID > costEstimationDataIDs(const CostEstimationData &match, bool useCompiledQueries=false, RelationalDBQueryResult *compiledQuery=NULL) const
virtual void removeFUArchitecture(RowID archID) const
virtual void removeBusEntry(RowID id) const
virtual void removeCostEstimationData(RowID id) const
CachedHDBManager(const std::string &hdbFile)
virtual RFImplementation * createImplementationOfRF(RowID id) const
virtual void removeRFArchitecture(RowID archID) const
virtual void removeCostFunctionPlugin(RowID pluginID) const
void createCostEstimatioDataIdsQuery(const CostEstimationData &match, std::string *query, RelationalDBQueryResult *compiledQuery=NULL, short int *queryHash=NULL, bool createBindableQuery=false) const
static void createNew(const std::string &file)
virtual void modifyCostFunctionPlugin(RowID id, const CostFunctionPlugin &plugin)
virtual void removeFUEntry(RowID id) const
std::string fileName() const
RelationalDBConnection * getDBConnection() const
virtual void removeFUImplementation(RowID implementationID) const
virtual std::set< RowID > costEstimationDataIDs(const CostEstimationData &match, bool useCompiledQueries=false, RelationalDBQueryResult *compiledQuery=NULL) const
virtual void removeSocketEntry(RowID id) const
virtual void removeRFImplementation(RowID implID) const
virtual void modifyCostEstimationData(RowID id, const CostEstimationData &data)
virtual RFArchitecture * rfArchitectureByID(RowID id) const
virtual DataObject costEstimationDataValue(const std::string &valueName, const std::string &pluginName) const
virtual void removeCostEstimationData(RowID id) const
virtual FUImplementation * createImplementationOfFU(FUArchitecture &architecture, RowID id) const
virtual void removeRFEntry(RowID id) const
RowID fuEntryIDOfImplementation(RowID implID) const
virtual void removeBusEntry(RowID id) const
virtual void removeRFArchitecture(RowID archID) const
RowID rfEntryIDOfImplementation(RowID implID) const
virtual FUArchitecture * fuArchitectureByID(RowID id) const
virtual void removeCostFunctionPlugin(RowID pluginID) const
virtual void removeFUArchitecture(RowID archID) const
virtual RFImplementation * createImplementationOfRF(RowID id) const
static HDBRegistry & instance()
void addHDB(CachedHDBManager *hdbManager)
CachedHDBManager & hdb(const std::string fileName)
bool hasHDB(const std::string &hdbFile)
static void deleteAllValues(MapType &aMap)
virtual RelationalDBQueryResult * query(const std::string &queryString, bool init=true)=0