编辑代码

#include <iostream>
#include <queue>
#include <list>
#include <tuple>

using namespace std;
namespace entity {
struct AdSkuInfo {

};
}
template<typename CacheValueType>
class ExpiredLruGcPtrValue {
    public:
    ExpiredLruGcPtrValue()
        : cache_time_(0)
        , pvalue_(NULL)
        , is_upgrade_(false)
    {
        // pvalue_ = new CacheValueType();
    }

    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();
            //value = gc_value->MutableValue();

            LruTupleType lru_value(key, gc_value);
            new_kv_queue_.push(std::move(lru_value));
            cout << "======  lru_value, " << key << " :  " << &lru_value << endl; 
            // Collect(gc_value);
        }
        inline void GetNode(ExpiredLruGcPtrValue<ValueType>** value) {
            if (!free_node_.empty()) {
                *value = free_node_.front();
                free_node_.pop();
            } else {
                *value = new ExpiredLruGcPtrValue<ValueType>();
                // cout << "====== ExpiredLruGcPtrValue GetNode : " << (*value)->pvalue_ << endl;
            }
        }
        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() {
    //JSRUN引擎2.0,支持多达30种语言在线运行,全仿真在线交互输入输出。 
	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;
}