cache.cxx
来自「vovida的软交换」· CXX 代码 · 共 591 行 · 第 1/2 页
CXX
591 行
/* ==================================================================== * 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/>. * */ /** * Cache.cxx -- 11/03/03 * * This provides a cache system to the clients, the cache deals with * the issues of finding the database etc, etc. */#include "Cache.hxx"#include "RecordTypes.h"#include "Record.hxx"#include "UpdateRegInfoRec.hxx"#include "DBResultset.hxx"#include "ConnectionManager.hxx"#include "CacheManager.hxx"#include "support.hxx"#include "cpLog.h"#include <sys/types.h>#include <unistd.h>#include <string>Cache* Cache::myInstance = NULL;int Cache::usageCount = 0;/** * Returns the existing instance of the Cache object * Or creates one if none exist * A basic implementation of the singleton design * pattern. * @return Cache* A pointer to the single instance of the Cache */Cache* Cache::getInstance() { // Standard singleton pattern, check if an instance exists if (myInstance == NULL) { // No existing instance myInstance = new Cache(); usageCount = 0; } cpLog(LOG_DEBUG, "Retrieving instance, user count is %d.", (usageCount+1)); usageCount++; return myInstance;}void Cache::freeInstance() { cpLog(LOG_DEBUG, "Freeing cache instance"); usageCount--;}void Cache::destroy() { if (myInstance) { cpLog(LOG_DEBUG, "Stopping manager threads"); // Stop the cache manager (the destructor automatically stops the thread) if (myInstance->myCacheManager) { (myInstance->myCacheManager)->shutdown(); (myInstance->myCacheManager)->join(); delete myInstance->myCacheManager; } // Stop the listeners from running myInstance->stopAllListeners(); // Nothing should be accessing the cache so delete the objects themselves. (myInstance->myCache)->empty(); // delete myDBManager; -- can't destory this ! if (myInstance->myDBThread){ delete myInstance->myDBThread; } cpLog(LOG_DEBUG, "Destroying Cache Object\n"); if (myInstance->myCache){ delete myInstance->myCache; } cpLog(LOG_DEBUG, "Deleting main cache instance"); usageCount = 0; delete myInstance; myInstance = NULL; }}Record* Cache::getRecord(RecordType rtype, KeyType key, bool useCache) { cpLog(LOG_DEBUG, "Fetching record of %s with key %s", Record::stringRecordType(rtype).c_str(), key.c_str()); Record *rec = NULL; if (useCache) { rec = myCache->get(rtype, key); } // 'rec' will be NULL if the object is not present if (rec == NULL) { cpLog(LOG_DEBUG, "Record not found in cache"); // Otherwise create a blank record rec = Record::createNewRecord(rtype); // Get a database connection DBConnection* dbconn = myDBManager->searchDBConPool(dbinfo); if (!dbconn) { cpLog(LOG_ERR, "Can't get database connection"); return NULL; } // And look up the database if (!rec->populateRecord(key, dbconn)) { delete rec; rec = NULL; cpLog(LOG_DEBUG, "Record is NULL!\n"); myDBManager->returnDBCon(dbconn); return rec; }; // Insert this into the cache if it exists (and we're using the cache) if (rec && useCache) { myCache->insert(rtype, key, rec); } myDBManager->returnDBCon(dbconn); } else { cpLog(LOG_DEBUG, "Object found in cache (will reinsert with correct access time)"); } // Sanity check that we created the right type of message if ((rec != NULL) && (rec->getRecordType() != rtype)) { // Only happens if Record subclass is incorrectly coded // Delete the rogue object and return NULL, we should probably really // ASSERT here as this is an error in the system cpLog(LOG_ERR, "getRecord() returned incorrect record type"); // Erase this from the cache as well, this will force a database lookup next time myCache->remove(rtype, key); delete rec; rec = NULL; } /* * The cache system is taking care of coping objects so we can just * return this pointer. */ return rec;}bool Cache::insertRecord(Record* rec) { cpLog(LOG_DEBUG, "Inserting record of type %s with key %s", (Record::stringRecordType(rec->getRecordType())).c_str(), rec->getKey().c_str()); // Get a database connection, that let the record insert itself DBConnection* dbconn = myDBManager->searchDBConPool(dbinfo); if (!dbconn) { cpLog(LOG_ERR, "Can't get database connection"); return false; } bool result = rec->insertRecord(dbconn); if (!result) cpLog(LOG_ERR, "Database insert failed"); myDBManager->returnDBCon(dbconn); // The update callback will automatically amend the cache if required, // if we did it here the update would be done twice return result;}bool Cache::changeRecord(Record* rec) { cpLog(LOG_DEBUG, "Changing record of type %s with key %s", (Record::stringRecordType(rec->getRecordType())).c_str(), rec->getKey().c_str()); // Get a database connection, that let the record insert itself DBConnection* dbconn = myDBManager->searchDBConPool(dbinfo); if (!dbconn) { cpLog(LOG_ERR, "Can't get database connection"); return false; } bool result = rec->amendRecord(dbconn); if (!result) cpLog(LOG_ERR, "Database change failed"); myDBManager->returnDBCon(dbconn); // The update callback will automatically amend the cache if required, // if we did it here the update would be done twice return result; }bool Cache::deleteRecord(Record* rec) { cpLog(LOG_DEBUG, "Deleting record of type %s with key %s", (Record::stringRecordType(rec->getRecordType())).c_str(), rec->getKey().c_str()); // Get a database connection, that let the record insert itself DBConnection* dbconn = myDBManager->searchDBConPool(dbinfo); if (!dbconn) { cpLog(LOG_ERR, "Can't get database connection"); return false; } bool result = rec->deleteRecord(dbconn); if (!result) cpLog(LOG_ERR, "Database delete failed"); myDBManager->returnDBCon(dbconn); // The update callback will automatically amend the cache if required, // if we did it here the update would be done twice return result;}bool Cache::registerForUpdates(string hostname, RecordType recType, callBackFuncPtr callBackFunc) { // Can't register to listen for update reg records as that would risk // creating loops, and only the clients should change them anyway if (recType == UPDATE_REG_INFO_RECORD) return false; cpLog(LOG_DEBUG, "Registering for update messages for records of type %s on %s",
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?