/* * Copyright (c) 2019 TAOS Data, Inc. * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the GNU Affero General Public License, version 3 * or later ("AGPL"), as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #ifndef TDENGINE_TCACHE_H #define TDENGINE_TCACHE_H #ifdef __cplusplus extern "C" { #endif #include "os.h" #include "tref.h" #include "hash.h" typedef struct SCacheStatis { int64_t missCount; int64_t hitCount; int64_t totalAccess; int64_t refreshCount; int32_t numOfCollision; } SCacheStatis; typedef struct SCacheDataNode { uint64_t addedTime; // the added time when this element is added or updated into cache uint64_t expiredTime; // expiredTime expiredTime when this element should be remove from cache uint64_t signature; uint32_t size; // allocated size for current SCacheDataNode uint16_t keySize : 15; bool inTrash : 1; // denote if it is in trash or not T_REF_DECLARE() char *key; char data[]; } SCacheDataNode; typedef struct STrashElem { struct STrashElem *prev; struct STrashElem *next; SCacheDataNode * pData; } STrashElem; typedef struct { int64_t totalSize; // total allocated buffer in this hash table, SCacheObj is not included. int64_t refreshTime; /* * to accommodate the old datanode which has the same key value of new one in hashList * when an new node is put into cache, if an existed one with the same key: * 1. if the old one does not be referenced, update it. * 2. otherwise, move the old one to pTrash, addedTime the new one. * * when the node in pTrash does not be referenced, it will be release at the expired expiredTime */ STrashElem * pTrash; void * tmrCtrl; void * pTimer; SCacheStatis statistics; SHashObj * pHashTable; int numOfElemsInTrash; // number of element in trash int16_t deleting; // set the deleting flag to stop refreshing ASAP. #if defined(LINUX) pthread_rwlock_t lock; #else pthread_mutex_t lock; #endif } SCacheObj; /** * * @param maxSessions maximum slots available for hash elements * @param tmrCtrl timer ctrl * @param refreshTime refresh operation interval time, the maximum survival time when one element is expired and * not referenced by other objects * @return */ SCacheObj *taosCacheInit(void *tmrCtrl, int64_t refreshTimeInSeconds); /** * add data into cache * * @param handle cache object * @param key key * @param pData cached data * @param dataSize data size * @param keepTime survival time in second * @return cached element */ void *taosCachePut(SCacheObj *pCacheObj, const char *key, const void *pData, size_t dataSize, int keepTimeInSeconds); /** * get data from cache * @param pCacheObj cache object * @param key key * @return cached data or NULL */ void *taosCacheAcquireByName(SCacheObj *pCacheObj, const char *key); /** * Add one reference count for the exist data, and assign this data for a new owner. * The new owner needs to invoke the taosCacheRelease when it does not need this data anymore. * This procedure is a faster version of taosCacheAcquireByName function, which avoids the sideeffect of the problem of * the data is moved to trash, and taosCacheAcquireByName will fail to retrieve it again. * * @param handle * @param data * @return */ void *taosCacheAcquireByData(SCacheObj *pCacheObj, void *data); /** * transfer the ownership of data in cache to another object without increasing reference count. * @param handle * @param data * @return */ void *taosCacheTransfer(SCacheObj *pCacheObj, void **data); /** * remove data in cache, the data will not be removed immediately. * if it is referenced by other object, it will be remain in cache * @param handle cache object * @param data not the key, actually referenced data * @param _remove force model, reduce the ref count and move the data into * pTrash */ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove); /** * move all data node into trash, clear node in trash can if it is not referenced by any clients * @param handle */ void taosCacheEmpty(SCacheObj *pCacheObj); /** * release all allocated memory and destroy the cache object. * * This function only set the deleting flag, and the specific work of clean up cache is delegated to * taosCacheRefresh function, which will executed every SCacheObj->refreshTime sec. * * If the value of SCacheObj->refreshTime is too large, the taosCacheRefresh function may not be invoked * before the main thread terminated, in which case all allocated resources are simply recycled by OS. * * @param handle */ void taosCacheCleanup(SCacheObj *pCacheObj); #ifdef __cplusplus } #endif #endif // TDENGINE_TCACHE_H