Permalink
Browse files

LruCache, feat: support expire event.

  • Loading branch information...
xicilion committed Dec 2, 2017
1 parent 205cef3 commit 46dd85fec2440aa82e86a52c913bd232fbf0b20e
Showing with 74 additions and 8 deletions.
  1. +20 −2 fibjs/include/LruCache.h
  2. +36 −3 fibjs/include/ifs/LruCache.h
  3. +2 −2 fibjs/src/util/LruCache.cpp
  4. +4 −1 idl/zh-cn/LruCache.idl
  5. +12 −0 test/util_test.js
View
@@ -7,6 +7,7 @@
#include "ifs/LruCache.h"
#include "ifs/Event.h"
#include "EventInfo.h"
#include "map"
#ifndef LRUCACHE_H_
@@ -35,6 +36,8 @@ class LruCache : public LruCache_base {
// object_base
virtual result_t toJSON(exlib::string key, v8::Local<v8::Value>& retVal);
EVENT_SUPPORT();
public:
// LruCache_base
virtual result_t get_size(int32_t& retVal);
@@ -49,11 +52,14 @@ class LruCache : public LruCache_base {
virtual result_t remove(exlib::string name);
virtual result_t isEmpty(bool& retVal);
public:
EVENT_FUNC(expire);
private:
class _linkedNode {
public:
date_t insert;
std::map<exlib::string, void *>::iterator m_prev, m_next, m_prev1, m_next1;
std::map<exlib::string, void*>::iterator m_prev, m_next, m_prev1, m_next1;
};
inline std::map<exlib::string, void*>::iterator _generalize(std::map<exlib::string, _linkedNode>::iterator it)
@@ -178,6 +184,18 @@ class LruCache : public LruCache_base {
}
}
void expire(std::map<exlib::string, _linkedNode>::iterator it)
{
obj_ptr<EventInfo> ei = new EventInfo(this, "expire");
ei->put("key", it->first);
ei->put("value", GetPrivate(it->first));
Variant v = ei;
_emit("expire", &v, 1);
remove(it);
}
void cleanup();
std::map<exlib::string, _linkedNode> m_datas;
@@ -187,7 +205,7 @@ class LruCache : public LruCache_base {
std::map<exlib::string, _linkedNode>::iterator m_begin;
std::map<exlib::string, _linkedNode>::iterator m_end;
std::map<exlib::string, obj_ptr<Event_base> > m_paddings;
std::map<exlib::string, obj_ptr<Event_base>> m_paddings;
int32_t m_size;
int32_t m_timeout;
@@ -13,10 +13,13 @@
*/
#include "../object.h"
#include "EventEmitter.h"
namespace fibjs {
class LruCache_base : public object_base {
class EventEmitter_base;
class LruCache_base : public EventEmitter_base {
DECLARE_CLASS(LruCache_base);
public:
@@ -33,6 +36,8 @@ class LruCache_base : public object_base {
virtual result_t set(v8::Local<v8::Object> map) = 0;
virtual result_t remove(exlib::string name) = 0;
virtual result_t isEmpty(bool& retVal) = 0;
virtual result_t get_onexpire(v8::Local<v8::Function>& retVal) = 0;
virtual result_t set_onexpire(v8::Local<v8::Function> newVal) = 0;
public:
template <typename T>
@@ -49,6 +54,8 @@ class LruCache_base : public object_base {
static void s_set(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_remove(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_isEmpty(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_get_onexpire(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& args);
static void s_set_onexpire(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args);
};
}
@@ -66,13 +73,14 @@ inline ClassInfo& LruCache_base::class_info()
static ClassData::ClassProperty s_property[] = {
{ "size", s_get_size, block_set, false },
{ "timeout", s_get_timeout, s_set_timeout, false }
{ "timeout", s_get_timeout, s_set_timeout, false },
{ "onexpire", s_get_onexpire, s_set_onexpire, false }
};
static ClassData s_cd = {
"LruCache", false, s__new, NULL,
ARRAYSIZE(s_method), s_method, 0, NULL, ARRAYSIZE(s_property), s_property, 0, NULL, NULL, NULL,
&object_base::class_info()
&EventEmitter_base::class_info()
};
static ClassInfo s_ci(s_cd);
@@ -246,6 +254,31 @@ inline void LruCache_base::s_isEmpty(const v8::FunctionCallbackInfo<v8::Value>&
METHOD_RETURN();
}
inline void LruCache_base::s_get_onexpire(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& args)
{
v8::Local<v8::Function> vr;
METHOD_NAME("LruCache.onexpire");
METHOD_INSTANCE(LruCache_base);
PROPERTY_ENTER();
hr = pInst->get_onexpire(vr);
METHOD_RETURN();
}
inline void LruCache_base::s_set_onexpire(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& args)
{
METHOD_NAME("LruCache.onexpire");
METHOD_INSTANCE(LruCache_base);
PROPERTY_ENTER();
PROPERTY_VAL(v8::Local<v8::Function>);
hr = pInst->set_onexpire(v0);
PROPERTY_SET_LEAVE();
}
}
#endif
@@ -27,12 +27,12 @@ void LruCache::cleanup()
t.now();
while ((it = m_end) != m_datas.end() && t.diff(it->second.insert) > m_timeout)
remove(it);
expire(it);
}
if (m_size > 0) {
while ((int32_t)m_datas.size() > m_size)
remove(m_end_lru);
expire(m_end_lru);
}
}
View
@@ -6,7 +6,7 @@
var c = new util.LruCache(10, 100);
```
*/
interface LruCache : object
interface LruCache : EventEmitter
{
/*! @brief LruCache 对象构造函数
@param size 缓存最大尺寸
@@ -62,4 +62,7 @@ interface LruCache : object
@return 容器内无数值则返回 true
*/
Boolean isEmpty();
/*! @brief 查询和绑定数据超时事件,相当于 on("expire", func); */
Function onexpire;
};
View
@@ -1260,6 +1260,15 @@ describe('util', () => {
});
it("size", () => {
c = new util.LruCache(3);
var vs = [],
ks = [];
c.onexpire = evt => {
ks.push(evt.key);
vs.push(evt.value);
};
assert.equal(c.size, 0);
c.set('a', 100);
@@ -1271,6 +1280,9 @@ describe('util', () => {
c.set('e', 400);
assert.equal(c.size, 3);
coroutine.sleep(1);
assert.deepEqual(ks, ['a', 'b']);
assert.deepEqual(vs, [100, 100]);
deepEqual(c.toJSON(), {
"e": 400,

0 comments on commit 46dd85f

Please sign in to comment.