⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cachestorage.cxx

📁 vovida的软交换
💻 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 + -