1 module hunt.cache.adapter.MemoryAdapter;
2 
3 import hunt.cache.adapter.Adapter;
4 import hunt.cache.Store;
5 
6 import hunt.cache.Nullable;
7 
8 import hunt.collection.Radix;
9 
10 import core.stdc.stdlib;
11 import core.stdc.string;
12 import core.stdc.time;
13 
14 import std.stdio;
15 
16 class MemoryAdapter : Adapter
17 {
18     Nullable!V get(V) (string key)
19     {
20         synchronized(this)
21         {
22             return get_inter!V(key);
23         }
24     }
25 
26     Nullable!V[string] getAll(V) (string[] keys)
27     {
28         Nullable!V[string] mapv;
29         synchronized(this)
30         {
31             foreach(k ; keys)
32             mapv[k] = get_inter!V(k);
33         }
34 
35         return mapv;
36     }
37 
38     bool hasKey(string key)
39     {
40         synchronized(this){
41             return find_inter(key, true);
42         }
43     }
44 
45     void set(V) (string key,  V value, uint expired = 0)
46     {
47         synchronized(this)
48         {
49             put_inter(key, value, expired);
50         }
51     }
52 
53     bool setIfAbsent(V) (string key,  V value)
54     {
55         synchronized(this)
56         {
57             if(!find_inter(key, false))
58             {    
59                 put_inter(key, value, 0);
60                 return true;
61             }
62             return false;    
63         }        
64     }
65 
66     void set(V) (V[string] maps, uint expired = 0)
67     {
68         synchronized(this)
69         {
70             foreach(k, v ; maps)
71             {
72                 put_inter(k, v, expired);
73             }
74         }
75     }
76 
77     bool remove(string key)
78     {
79         synchronized(this)
80         {
81             return remove_inter(key);
82         }
83     }
84 
85     void remove(string[] keys)
86     {
87         synchronized(this)
88         {
89             foreach( k ; keys)
90             {
91                 remove_inter(k);
92             }
93         }
94     }
95 
96     void clear()
97     {
98         synchronized(this)
99         {
100             rax_data.clear();
101             rax_time.clear();
102         }
103     }
104 
105     this()
106     {
107         rax_data = Radix.create();
108         rax_time = Radix.create();
109     }
110 
111     ~this()
112     {
113         Radix.free(rax_data);
114         Radix.free(rax_time);
115     }
116 
117 protected:
118 
119     Radix *rax_data;
120     Radix *rax_time;
121 
122     bool find_inter(string key, bool free)
123     {
124         Nullable!uint tick = get_inter!uint(rax_time, key);
125         if(tick.isNull)
126         {
127             void *data;
128             return rax_data.find(cast(ubyte[])key,data);
129         }
130         else{
131             uint now = cast(uint)time(null);
132             if( tick.origin < now )
133             {
134                 if(free)
135                 {
136                     remove_inter(key);
137                 }
138                 return false;
139             }
140             else{
141                 return true;
142             }
143         }
144     }
145 
146     Nullable!V get_inter(V) (string key)
147     {
148         Nullable!uint tick =  get_inter!uint(rax_time, key);
149 
150         if(tick.isNull)    //not set ttl
151         {
152             return get_inter!V(rax_data, key);
153         }
154         else{
155             uint now = cast(uint)time(null);
156             if( tick.origin < now) // remove
157             {
158                 remove_inter(key);
159                 return Nullable!V.init;
160             }
161             else
162             {
163                 return get_inter!V(rax_data, key);
164             }
165         }
166     }
167 
168     Nullable!V get_inter(V) (Radix *r,string key)
169     {
170         void *data;
171         if (!r.find(cast(ubyte[])key, data))
172             return Nullable!V.init;
173 
174         uint len;
175         memcpy(&len, data, 4);
176         byte[] byDatas = new byte[len];
177         memcpy(byDatas.ptr, data + 4, len);
178         return DeserializeToObject!V(byDatas);
179     }
180 
181     void put_inter(V) (string key, V v, uint expired)
182     {
183         if(expired == 0)
184             put_inter(rax_data, key, v);
185         else{
186             put_inter!uint(rax_time, key, expired + cast(uint)time(null));
187             put_inter(rax_data, key, v);
188         }
189     }
190 
191     void put_inter(V) (Radix *r, string key,  V v)
192     {
193         byte[] data = SerializeToByte(v);
194 
195         void *value = malloc(data.length + 4);
196         uint len = cast(uint) data.length;
197         memcpy(value, &len, 4);
198         memcpy(value + 4, data.ptr, data.length);
199         r.insert(cast(ubyte[])key, value);
200     }
201 
202     bool remove_inter(string key)
203     {
204         if(rax_data.remove(cast(ubyte[])key))
205         {
206             rax_time.remove(cast(ubyte[])key);
207             return true;
208         }
209 
210         return false;
211     }
212 
213     bool remove_inter(Radix *r, string key)
214     {    
215         return r.remove(cast(ubyte[])key);    
216     }
217 }