forked from gnbdev/opengnb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgnb_lru32.h
116 lines (78 loc) · 5.88 KB
/
gnb_lru32.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#ifndef gnb_lru32_h
#define gnb_lru32_h
#include <stdio.h>
#include <stdint.h>
#include "gnb_alloc.h"
#include "gnb_fixed_pool.h"
#include "gnb_hash32.h"
#include "gnb_doubly_linked_list.h"
typedef struct _gnb_lru32_t gnb_lru32_t;
typedef struct _gnb_lru32_node_t gnb_lru32_node_t;
typedef struct _gnb_lru32_node_t{
gnb_doubly_linked_list_node_t *dl_node; // dll_node->data -> gnb_lru32_node_t*
gnb_kv32_t *kv; // 保存在 hashmap 中的kv,使得在双向链表这端可以通过key去存取 hashmap
void *udata; // -> lru payload
}gnb_lru32_node_t;
typedef struct _gnb_lru32_t{
gnb_heap_t *heap;
gnb_doubly_linked_list_t *doubly_linked_list;
gnb_hash32_map_t *lru_node_map; //save type: gnb_lru32_node_t
uint32_t size;
uint32_t max_size;
//lru 可以存数据的指针也可以申请一块内存把数据拷贝到该内存块
//存入的数据块的大小,如果为0,用同样的key每次set进去都要释放此前为存储数据块申请的内存,
//如果不等于0,存入数据的时候就使用之前申请好的内存
uint32_t block_size;
gnb_fixed_pool_t *lru_node_fixed_pool;
gnb_fixed_pool_t *dl_node_fixed_pool;
gnb_fixed_pool_t *udata_fixed_pool;
}gnb_lru32_t;
/*
如果用 gnb_lru32_set 和 gnb_lru32_store 保存 数据 到 lru, block_size 设为0
如果用 gnb_lru32_block_set 保存 数据 到 lru, block_size 设为 block 的大小,这对于保存一些容量相同的数据,可以避免频繁申请/释放内存
*/
gnb_lru32_t *gnb_lru32_create(gnb_heap_t *heap, uint32_t max_size,uint32_t block_size);
//需要释放完 lru 里的lru_node->udata,才能执行这个函数
//释放到操作是 迭代执行 gnb_lru32_pop_head 或 gnb_lru32_pop_tail,直到返回为NULL
//由于lru_node->udata存放的是调用者的私有数据,因此释放时需要由调用者自行处理
void gnb_lru32_release(gnb_lru32_t *lru);
//这个函数传入的 data 需要调用者申请内存和释放内存
//如果set入data前发现链表已经满了,就立即返回当前传入的data由调用者释放
//如果set入data后发现链表满了,就dropt掉tail,并返回tail的data由调用者释放
void* gnb_lru32_put(gnb_lru32_t *lru, unsigned char *key, uint32_t key_len, void *data);
#define GNB_LRU32_PUT(lru,key,key_len,data) gnb_lru32_put(lru, (unsigned char *)key, (uint32_t)key_len, data)
//传入的 data 会在 lru 内部申请一块内存,拷贝一份,当链表满了需要丢弃tail的节点时,tail节点绑定的这块内存也会被gnb_lru32_set释放
void gnb_lru32_store(gnb_lru32_t *lru, unsigned char *key, uint32_t key_len, void *data, uint32_t size);
#define GNB_LRU32_STORE(lru,key,key_len,data,size) gnb_lru32_store(lru, (unsigned char *)key, (uint32_t)key_len, data, (uint32_t)size)
//传入的data会拷贝到lru中一块内存里,相同的key存入数据会覆盖之前的数据,
//每个key对应的内存块是预先申请好的,大小一致的,在调用gnb_lru32_creates时通过block_size设定
//用这个函数保存小块数据到lru是效率最高的,不需要频繁申请/释放内存
void gnb_lru32_fixed_store(gnb_lru32_t *lru, unsigned char *key, uint32_t key_len, void *data);
#define GNB_LRU32_FIXED_STORE(lru,key,key_len,data) gnb_lru32_fixed_store(lru,(unsigned char *)key,(uint32_t)key_len, data)
//这个函数不会把命中的节点移到链表首部,需要调用 gnb_lru32_movetohead 实现
gnb_lru32_node_t* gnb_lru32_hash_get(gnb_lru32_t *lru, unsigned char *key, uint32_t key_len);
#define GNB_LRU32_HASH_GET(lru,key,key_len) gnb_lru32_hash_get(lru,key,(uint32_t)key_len);
//如果命中,会调用 gnb_lru32_movetohead 把命中的节点移动到链表首部
gnb_lru32_node_t* gnb_lru32_get(gnb_lru32_t *lru, unsigned char *key, uint32_t key_len);
#define GNB_LRU32_GET(lru,key,key_len) gnb_lru32_get(lru,key,(uint32_t)key_len);
#define GNB_LRU32_VALUE(b) b!=NULL?b->udata:NULL
#define GNB_LRU32_HASH_GET_VALUE(lru,key,key_len) GNB_LRU32_VALUE( gnb_lru32_hash_get(lru, (unsigned char *)key, (uint32_t)key_len) )
#define GNB_LRU32_GET_VALUE(lru,key,key_len) GNB_LRU32_VALUE( gnb_lru32_get(lru, (unsigned char *)key, (uint32_t)key_len) )
void gnb_lru32_movetohead(gnb_lru32_t *lru, unsigned char *key, uint32_t key_len);
#define GNB_LRU32_MOVETOHEAD(lru,key,key_len) gnb_lru32_movetohead(lru, (unsigned char *)key, (uint32_t)key_len)
void* gnb_lru32_pop_by_key(gnb_lru32_t *lru, unsigned char *key, uint32_t key_len);
#define GNB_LRU32_POP_BY_KEY(lru,key,key_len) gnb_lru32_pop_by_key(lru,key,(uint32_t)key_len)
void* gnb_lru32_pop_head(gnb_lru32_t *lru);
void* gnb_lru32_pop_tail(gnb_lru32_t *lru);
void* gnb_lru32_get_head(gnb_lru32_t *lru);
void* gnb_lru32_get_tail(gnb_lru32_t *lru);
#define GNB_LRU32_UINT32_PUT(lru,key,data) gnb_lru32_put(lru, (unsigned char *)(&key), sizeof(uint32_t), data)
#define GNB_LRU32_UINT32_STORE(lru,key,data,size) gnb_lru32_store(lru, (unsigned char *)(&key), sizeof(uint32_t), data, (uint32_t)size)
#define GNB_LRU32_UINT32_FIX_STORE(lru,key,data) gnb_lru32_fix_store(lru, (unsigned char *)(&key), sizeof(uint32_t), data)
#define GNB_LRU32_UINT32_HASH_GET(lru,key) gnb_lru32_hash_get(lru,(unsigned char *)*&key),sizeof(uint32_t));
#define GNB_LRU32_UINT32_GET(lru,key) gnb_lru32_get(lru,(unsigned char *)(&key),sizeof(uint32_t));
#define GNB_LRU32_UINT32_POP_BY_KEY(lru,key) gnb_lru32_pop_by_key(lru, (unsigned char *)(&key), sizeof(uint32_t))
#define GNB_LRU32_UINT32_MOVETOHEAD(lru,key) gnb_lru32_movetohead(lru, (unsigned char *)(&key), sizeof(uint32_t))
#define GNB_LRU32_UINT32_HASH_GET_VALUE(lru,key) GNB_LRU32_VALUE( gnb_lru32_hash_get(lru, (unsigned char *)(&key), sizeof(uint32_t)) )
#define GNB_LRU32_UINT32_GET_VALUE(lru,key) GNB_LRU32_VALUE( gnb_lru32_get(lru, (unsigned char *)(&key), sizeof(uint32_t)) )
#endif