using namespace std;
namespace entity {
struct AdSkuInfo {
};
}
template<typename CacheValueType>
class ExpiredLruGcPtrValue {
public:
ExpiredLruGcPtrValue()
: cache_time_(0)
, pvalue_(NULL)
, is_upgrade_(false)
{
}
CacheValueType* Value() {
return pvalue_;
}
CacheValueType** MutableValue() {
return &pvalue_;
}
void SetValue(CacheValueType** pvalue) {
pvalue_ = *pvalue;
}
void InitValue() {
if (pvalue_ == nullptr) {
pvalue_ = new CacheValueType();
}
}
public:
bool is_upgrade_;
int64_t cache_time_;
CacheValueType* pvalue_;
};
template<typename KeyType, typename ValueType>
class ExpiredLruGcCache {
public:
typedef std::tuple<KeyType, ExpiredLruGcPtrValue<ValueType>*> LruTupleType;
struct GC_Element {
int64_t time;
ExpiredLruGcPtrValue<ValueType> * item_ptr;
GC_Element(int64_t tm, ExpiredLruGcPtrValue<ValueType> * val) :time(tm), item_ptr(val){}
};
ExpiredLruGcCache(int count) {
cout << "ExpiredLruGcCache: key, value" << endl;
Init(count);
}
void Init(int count) {
ExpiredLruGcPtrValue<ValueType> * value = new ExpiredLruGcPtrValue<ValueType>[count];
if (value) {
cout << "====== Init ExpiredLruGcPtrValue" << endl;
for (size_t i = 0; i < count; ++i) {
value[i].InitValue();
free_node_.push(value + i);
cout << "====== Init, " << i << " : " << value[i].pvalue_ << endl;
}
}
}
void Print() {
cout << "This is Base ExpiredLruGcCache" << endl;
}
void GetEmptyAdSkuInfo(KeyType key, ValueType** value) {
ExpiredLruGcPtrValue<ValueType>* gc_value;
GetNode(&gc_value);
if (gc_value == nullptr) {
return;
}
if (!gc_value->Value()) {
gc_value->InitValue();
}
*value = gc_value->Value();
LruTupleType lru_value(key, gc_value);
new_kv_queue_.push(std::move(lru_value));
cout << "====== lru_value, " << key << " : " << &lru_value << endl;
}
inline void GetNode(ExpiredLruGcPtrValue<ValueType>** value) {
if (!free_node_.empty()) {
*value = free_node_.front();
free_node_.pop();
} else {
*value = new ExpiredLruGcPtrValue<ValueType>();
}
}
inline void Collect(ExpiredLruGcPtrValue<ValueType>* value) {
gc_.push_back(GC_Element(0, value));
}
void PrintGc() {
cout << "PrintGc gc : " << gc_.size() << endl;
int i = 0;
while (!gc_.empty()) {
const GC_Element& element = gc_.front();
cout << "------ gc_, " << i << " : " << element.item_ptr->pvalue_ << endl;
++i;
gc_.pop_front();
free_node_.push(element.item_ptr);
}
}
void PrintKvQueue() {
cout << "PrintKvQueue new_kv_queue : " << new_kv_queue_.size() << endl;
while (!new_kv_queue_.empty()) {
LruTupleType lru_value;
lru_value = new_kv_queue_.front();
new_kv_queue_.pop();
ExpiredLruGcPtrValue<ValueType>* new_value = std::get<1>(lru_value);
if (new_value == nullptr) {
cout << "====== new_value: " << (new_value == nullptr) << endl;
continue;
}
if (new_value->Value() == nullptr) {
cout << "====== Mutable_Value: " << (new_value->Value() == nullptr) << endl;
continue;
}
Collect(new_value);
cout << "====== lru_value, " << " : " << &lru_value
<< ", " << new_value->Value() << endl;
}
}
void PrintFreeNode() {
cout << "PrintFreeNode free_node : " << free_node_.size() << endl;
int i = 0;
while (!free_node_.empty()) {
ExpiredLruGcPtrValue<ValueType>* gc_value;
gc_value = free_node_.front();
free_node_.pop();
cout << ">>>>>> free_node_, " << i << " : " << gc_value->pvalue_ << endl;
++i;
}
}
public:
std::queue<ExpiredLruGcPtrValue<ValueType>*> free_node_;
std::queue<LruTupleType> new_kv_queue_;
std::list<GC_Element> gc_;
};
int main() {
cout << "Hello world! - cpp.jsrun.net." << endl;
int init_count = 30;
ExpiredLruGcCache<int64_t, entity::AdSkuInfo> lru_cache(init_count);
int need_conut = 50;
for (int i = 0; i < need_conut; ++i) {
entity::AdSkuInfo* ad_info = nullptr;
lru_cache.GetEmptyAdSkuInfo(i, &ad_info);
cout << "++++++ ad_info, " << i << " : " << ad_info << endl;
}
cout << "free_node_ : " << lru_cache.free_node_.size() << endl;
cout << "gc : " << lru_cache.gc_.size() << endl;
cout << "new_kv_queue : " << lru_cache.new_kv_queue_.size() << endl;
lru_cache.PrintKvQueue();
lru_cache.PrintGc();
lru_cache.PrintFreeNode();
cout << "free_node_ : " << lru_cache.free_node_.size() << endl;
cout << "gc : " << lru_cache.gc_.size() << endl;
cout << "new_kv_queue : " << lru_cache.new_kv_queue_.size() << endl;
return 0;
}