增加LRUCache

This commit is contained in:
hyzboy 2019-05-15 10:15:03 +08:00
parent f18bcfd0b4
commit c8a09d4f5e
2 changed files with 432 additions and 0 deletions

354
inc/hgl/type/LRUCache.cpp Normal file
View File

@ -0,0 +1,354 @@
#ifndef HGL_TYPE_LRU_CACHE_CPP
#define HGL_TYPE_LRU_CACHE_CPP
#include<hgl/LogInfo.h>
namespace hgl
{
/**
*
* @param value
*/
template<typename F,typename T>
LRUCache<F,T>::LRUCache(int value)
{
if(value<=0)
{
LOG_ERROR(OS_TEXT("ActiveChain缓冲区大小被设置<=0"));
value=3;
}
count=0;
max_count=value;
start_item=nullptr;
end_item=nullptr;
}
template<typename F,typename T>
LRUCache<F,T>::~LRUCache()
{
Clear();
}
template<typename F,typename T>
void LRUCache<F,T>::SetMaxCount(int value)
{
if(value<=0)
{
LOG_ERROR(OS_TEXT("ActiveChain缓冲区大小被设置<=0此次设置无效"));
}
else
max_count=value;
}
template<typename F,typename T>
bool LRUCache<F,T>::Create(const F &,T &)
{
return true;
}
template<typename F,typename T>
void LRUCache<F,T>::Clear(const F &,T &)
{
}
template<typename F,typename T>
void LRUCache<F,T>::ClearEnd()
{
LruItem *temp=end_item->prev;
Clear(end_item->key,end_item->value);
delete end_item;
end_item=temp;
if(end_item) //如果只有一个数据end_item会为NULL
end_item->next=nullptr;
else
{
#ifdef _DEBUG
if(count!=1)
{
LOG_ERROR(OS_TEXT("ActiveChain出错end_item=nullptr,count!=1"));
}
#endif//
start_item=nullptr; //如果end_item为空start_item也应该为空
}
count--;
}
/**
*
* @param key
* @param value
*/
template<typename F,typename T>
LRUCacheItem<F,T> *LRUCache<F,T>::Add(const F &key,const T &value)
{
LruItem *temp;
while(count>=max_count)ClearEnd(); //满了,清除超出的数据
temp=new LruItem;
temp->key=key;
temp->value=value;
temp->prev=nullptr;
temp->next=start_item;
if(start_item) //如果还没有数据,start会为NULL
start_item->prev=temp;
start_item=temp; //将当前数据设成start_item
count++;
if(!end_item)
{
#ifdef _DEBUG //理由上end_item为NULL时应该是没有数据
if(count!=1)
{
LOG_ERROR(OS_TEXT("ActiveChain出错end_item=nullptr,count!=1"));
}
else
#endif//_DEBUG
end_item=start_item;
}
return(temp);
}
template<typename F,typename T>
void LRUCache<F,T>::MoveToStart(LruItem *item)
{
if(item==start_item)
return;
//不是首节点,这个情况下count肯定>1
if(item!=end_item) //也不是尾节点,这个情况下count肯定>2
{
if(item->next)
item->next->prev=item->prev;
if(item->prev)
item->prev->next=item->next;
start_item->prev=item;
item->prev=nullptr;
item->next=start_item;
start_item=item;
}
else //为尾节点
{
end_item=end_item->prev;
end_item->next=nullptr;
item->prev=nullptr;
item->next=start_item;
start_item->prev=item;
start_item=item;
}
}
/**
* ,,,false
* @param key
* @param value
* @param mts
* @return
*/
template<typename F,typename T>
bool LRUCache<F,T>::Find(const F &key,T &value,bool mts)
{
if(count<=0)return(false);
int n=count;
LruItem *temp=start_item;
while(n--)
{
if(temp->key==key)
{
value=temp->value;
if(mts)
MoveToStart(temp);
return(true);
}
else
temp=temp->next;
}
return(false);
}
/**
* ,,Create创建数据,false
* @param key
* @param value
* @param mts
* @return true/false
*/
template<typename F,typename T>
bool LRUCache<F,T>::Get(const F &key,T &value,bool mts)
{
if(Find(key,value,mts))
return(true);
while(count>=max_count)ClearEnd(); //满了,清除超出的数据
if(Create(key,value))
{
Add(key,value);
return(true);
}
return(false);
}
/**
*
*/
template<typename F,typename T>
void LRUCache<F,T>::Clear()
{
if(count<=0)return;
int n=0;
LruItem *temp=start_item;
while(temp)
{
LruItem *obj=temp;
Clear(obj->key,obj->value);
temp=obj->next;
delete obj;
n++;
}
if(n!=count)
{
LOG_ERROR(OS_TEXT("LRUCache Count=")+OSString(count)+OS_TEXT(",Clear=")+OSString(n));
}
count=0;
start_item=nullptr;
end_item=nullptr;
}
template<typename F,typename T>
void LRUCache<F,T>::Delete(LruItem *obj)
{
if(!obj)return;
Clear(obj->key,obj->value);
if(count>1)
{
if(obj==start_item)
{
start_item=obj->next;
start_item->prev=nullptr;
}
else
if(obj==end_item)
{
end_item=obj->prev;
end_item->next=nullptr;
}
else
{
obj->prev->next=obj->next;
obj->next->prev=obj->prev;
}
}
else
{
start_item=nullptr;
end_item=nullptr;
}
delete obj;
count--;
}
template<typename F,typename T>
void LRUCache<F,T>::DeleteByKey(const F &key)
{
if(count<=0)return;
int n=count;
LruItem *temp=start_item;
while(n--)
{
if(temp->key==key)
{
Delete(temp);
return;
}
temp=temp->next;
}
}
template<typename F,typename T>
void LRUCache<F,T>::DeleteByValue(T &value)
{
if(count<=0)return;
int n=count;
LruItem *temp=start_item;
while(n--)
{
if(temp->value==value)
{
Delete(temp);
return;
}
temp=temp->next;
}
}
// template<typename F,typename T>
// bool LRUCache<F,T>::Update(const F &key,T &value)
// {
// if(Find(key,value,false))
// {
// LruItem *obj=temp;
//
// Clear(obj->key,obj->value);
//
// Create(obj->key,obj->value);
//
// return(true);
// }
//
// if(Create(key,value))
// {
// Add(key,value);
//
// return(true);
// }
//
// return(false);
// }
}//namespace hgl
#endif//HGL_TYPE_LRU_CACHE_CPP

78
inc/hgl/type/LRUCache.h Normal file
View File

@ -0,0 +1,78 @@
#ifndef HGL_TYPE_LRU_CACHE_INCLUDE
#define HGL_TYPE_LRU_CACHE_INCLUDE
#include<hgl/type/List.h>
namespace hgl
{
template<typename F,typename T> struct LRUCacheItem
{
F key; //识别标识
T value; //数据
LRUCacheItem<F,T> *prev, //前一数据
*next; //后一数据
};//template<typename F,typename T> struct LRUCacheItem
/**
* 使(使)<br>
* 使使<br>
* 使
*/
template<typename F,typename T> class LRUCache ///缓冲区管理模板(以最终使用时间为基准)
{
public:
using LruItem=LRUCacheItem<F,T>;
protected:
LruItem *start_item, //首数据
*end_item; //尾数据
int count,max_count;
protected:
virtual bool Create(const F &,T &); ///<创建数据
virtual void Clear(const F &,T &); ///<清除数据
void MoveToStart(LruItem *); ///<移动某一个数据到最前面
void Delete(LruItem *); ///<清除某一个数据
void ClearEnd(); ///<清除最后一个数据
public:
const int GetCount ()const{return count;} ///<取得当前有多少数据
const int GetMaxCount ()const{return max_count;} ///<取得最大可以有多少数据
virtual void SetMaxCount (int); ///<设置最大可以有多少数据
int GetFreeCount()const{return max_count-count;} ///<取得当前缓冲区剩于量
public:
LRUCache(int);
virtual ~LRUCache();
virtual LruItem * Add (const F &,const T &); ///<增加一个数据
virtual bool Find (const F &,T &,bool=true); ///<取得一个数据(如果没有不会自动创建)
virtual bool Get (const F &,T &,bool=true); ///<取得一个数据(如果没有会自动创建)
void Clear (); ///<清除所有数据
LruItem * GetEnd (bool mts=true) ///<取最后一项
{
LruItem *obj=end_item;
if(mts)
MoveToStart(obj);
return(obj);
}
void DeleteByKey(const F &);
void DeleteByValue(T &);
// bool Update (const F &,T &); ///<更新数据
};//template<typename F,typename T> class LRUCache
}//namespace hgl
#include<hgl/type/LRUCache.cpp>
#endif//HGL_TYPE_LRU_CACHE_INCLUDE