1 module hunt.cache.memory; 2 3 import hunt.cache.cache; 4 import hunt.cache.store; 5 import hunt.cache.nullable; 6 import hunt.cache.Radix; 7 8 import core.stdc.stdlib; 9 import core.stdc.string; 10 import core.stdc.time; 11 12 import std.stdio; 13 14 public: 15 class MemoryCache 16 { 17 18 //interface 19 20 Nullable!V get(V)(string key) 21 { 22 synchronized(this) 23 { 24 return get_inter!V(key); 25 } 26 } 27 28 Nullable!V[string] getall(V)(string[] keys) 29 { 30 Nullable!V[string] mapv; 31 synchronized(this) 32 { 33 foreach(k ; keys) 34 mapv[k] = get_inter!V(k); 35 } 36 37 return mapv; 38 } 39 40 bool containsKey(string key) 41 { 42 synchronized(this){ 43 return find_inter(key , true); 44 } 45 } 46 47 void put(V)(string key , V v , uint expired = 0) 48 { 49 synchronized(this) 50 { 51 put_inter(key , v , expired); 52 } 53 } 54 55 bool putifAbsent(V)(string key , V v) 56 { 57 synchronized(this) 58 { 59 if(!find_inter(key , false)) 60 { 61 put_inter(key , v , 0); 62 return true; 63 } 64 return false; 65 } 66 } 67 68 void putAll(V)( V[string] maps , uint expired = 0) 69 { 70 synchronized(this){ 71 foreach(k , v ; maps) 72 { 73 put_inter(k , v , expired); 74 } 75 } 76 } 77 78 bool remove(string key) 79 { 80 synchronized(this) 81 { 82 return remove_inter(key); 83 } 84 } 85 86 void removeAll(string[] keys) 87 { 88 synchronized(this) 89 { 90 foreach( k ; keys) 91 { 92 remove_inter(k); 93 } 94 } 95 } 96 97 void clear() 98 { 99 synchronized(this){ 100 rax_data.Clear(); 101 rax_time.Clear(); 102 } 103 } 104 105 this(string args = "") 106 { 107 rax_data = rax.New(); 108 rax_time = rax.New(); 109 } 110 111 ~this() 112 { 113 rax.Free(rax_data); 114 rax.Free(rax_time); 115 } 116 117 protected: 118 119 rax *rax_data; 120 rax *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)(rax *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)(rax *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(rax *r , string key) 214 { 215 return r.Remove(cast(ubyte[])key); 216 } 217 }