📄 cachestorage.cxx
字号:
/* ==================================================================== * The Vovida Software License, Version 1.0 * * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names "VOCAL", "Vovida Open Communication Application Library", * and "Vovida Open Communication Application Library (VOCAL)" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor * may "VOCAL" appear in their name, without prior written * permission of Vovida Networks, Inc. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * ==================================================================== * * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc. For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */ #include "CacheStorage.hxx"#include "Record.hxx"#include "Lock.hxx"#include "Mutex.hxx"#include "DBTypes.h"#include "cpLog.h"#include <ctime>using Vocal::Threads::Mutex;using Vocal::Threads::Lock;/* * Cache access functions */inner_cache* CacheStorage::getInnerCache(RecordType rtype, bool createIfMissing) { outer_cache_itr i = myCache->find(rtype); if (i != myCache->end()) { // Found it ! return (i->second); } else { // Not found it if (createIfMissing) { inner_cache* ic = new inner_cache; myCache->insert(rtype_map_pair(rtype, ic)); return ic; } } return NULL;}Record* CacheStorage::get(RecordType rtype, KeyType key) { cpLog(LOG_DEBUG, "Locked cache for get"); Lock lock(*myMutex); // Get the record set, don't create it if it's not there inner_cache* innerCachePtr = getInnerCache(rtype, false); // Return NULL if it's not there if (innerCachePtr == NULL) { cpLog(LOG_DEBUG, "Record type not found, unlocking cache"); return NULL; } // Find the record in this inner_cache_itr i = innerCachePtr->find(key); // if not found return null if (i == innerCachePtr->end()) { cpLog(LOG_DEBUG, "Key not found, unlocked cache!"); return NULL; } cpLog(LOG_DEBUG, "Found record, updateing timestamp and unlocked cache!"); // Found it, update the timestamp and return a copy ((i->second)->setLastAccessed(time(NULL))); return ((i->second)->clone());}void CacheStorage::insert(RecordType rtype, KeyType key, Record* rec) { cpLog(LOG_DEBUG, "Locked cache for insert"); Lock lock(*myMutex); // Get the record set, create it if it's not there inner_cache* innerCachePtr = getInnerCache(rtype, true); // Find the record in this inner_cache_itr i = innerCachePtr->find(key); // if found then remove it if (i != innerCachePtr->end()) { Record* oldRec = i->second; innerCachePtr->erase(key); delete oldRec; }; rec->setLastAccessed(time(NULL)); // Now insert a copy of the fresh information innerCachePtr->insert(key_record_pair(key, rec->clone())); cpLog(LOG_DEBUG, "Insert done, unlocked cache!");}/* void CacheStorage::replaceInCache(RecordType rtype, KeyType key, Record* rec) {} */void CacheStorage::remove(RecordType rtype, KeyType key) { cpLog(LOG_DEBUG, "Locked cache for remove"); Lock lock(*myMutex); // Get the inner map for this record inner_cache* innerCachePtr = getInnerCache(rtype, false); // If there is no inner map there is nothing to erase if (innerCachePtr == NULL) { cpLog(LOG_DEBUG, "Not matching record type, Unlocked cache!"); return; } // Now search this inner map for the key inner_cache_itr i = innerCachePtr->find(key); if (i != innerCachePtr->end()) { // Found it, remove it Record* oldRec = i->second; innerCachePtr->erase(key); // The cache member was a 'clone' so we need to discard it delete oldRec; cpLog(LOG_DEBUG, "Done remove, unlocked cache!"); } else { cpLog(LOG_DEBUG, "No record to remove, unlocked cache!"); }}void CacheStorage::empty() { cpLog(LOG_DEBUG, "Locked cache for cache empty"); Lock lock(*myMutex); outer_cache_itr i; inner_cache* innerCachePtr; inner_cache_itr j; for (i = myCache->begin();i != myCache->end( );i++) { innerCachePtr = i->second; for (j = innerCachePtr->begin(); j != innerCachePtr->end(); j++) { // Found an inner entry, delect the Record object delete (j->second); // Erase that from the map innerCachePtr->erase(j->first); } // Now remove the inner map as well delete innerCachePtr; } cpLog(LOG_DEBUG, "Cache empty, unlocked cache");}void CacheStorage::purge(int lastValidTime) { cpLog(LOG_DEBUG, "Locked cache for purge"); Lock lock(*myMutex); outer_cache_itr oldestOuter; inner_cache_itr oldestInner; time_t oldestTime = time(NULL); // This flag stops the whole thing bombing if the database is empty bool foundRecord = false; int recordsDeleted = 0; outer_cache_itr i; inner_cache* innerCachePtr; inner_cache_itr j; for (i = myCache->begin();i != myCache->end( );i++) { innerCachePtr = i->second; for (j = innerCachePtr->begin(); j != innerCachePtr->end(); j++) { /* * This section is executed for each item in the cache */ // If this record is older than the valid time then delete anyway if ((j->second)->getLastAccessed() < lastValidTime ) { cpLog(LOG_DEBUG, "Record %s too old, deleting", (j->first).c_str()); delete j->second; innerCachePtr->erase(j->first); recordsDeleted++; } else { if (recordsDeleted == 0) { // If we still haven't deleted anything keep looking for the // oldest record if ( (j->second)->getLastAccessed() < oldestTime ) { // This is older than our last one; oldestOuter = i; oldestInner = j; oldestTime = (j->second)->getLastAccessed(); foundRecord = true; } } // recordsDeleted == 0 } // if ((j->second)->getLastAccessed() < lastValidTime ) {...} else } // for j } // for i // If we still haven't deleted anything then delete the oldest record. if ((recordsDeleted == 0) && (foundRecord)) { cpLog(LOG_DEBUG, "Removing record (%s) as it is the oldest", oldestInner->first.c_str()); (oldestOuter->second)->erase(oldestInner->first); delete oldestInner->second; recordsDeleted++; } // Could check to see if the inner cache is empty and delete it also // TODO cpLog(LOG_DEBUG, "Purge done, deleted %d records, unlocked cache!", recordsDeleted);}int CacheStorage::size() { int size = 0; outer_cache_itr i = myCache->begin(); for (;i != myCache->end( );i++) { size += (i->second)->size(); } return size;}/* * Debug routine */void CacheStorage::display() { outer_cache_itr i = myCache->begin(); inner_cache* innerCachePtr; inner_cache_itr j; cout << "CacheStorage.cxx:\t===CACHE DUMP===\n"; for (;i != myCache->end( );i++) { cout << "CacheStorage.cxx:\tCache entries for record type " << i->first << "\n"; innerCachePtr = i->second; for (j = innerCachePtr->begin(); j != innerCachePtr->end(); j++) { cout << "CacheStorage.cxx:\t======ENTRY======\n"; (j->second)->displayRecord(); cout << "CacheStorage.cxx:\t====END ENTRY====\n"; } } cout << "CacheStorage.cxx:\tEND OF CACHE DUMP\n";}CacheStorage::CacheStorage() { myCache = new outer_cache; myMutex = new Mutex;} CacheStorage::~CacheStorage() { delete myCache; delete myMutex;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -