1 package com.foxinmy.weixin4j.cache;
2
3 import java.util.ArrayList;
4 import java.util.Date;
5 import java.util.HashSet;
6 import java.util.List;
7 import java.util.Set;
8
9 import com.whalin.MemCached.MemCachedClient;
10 import com.whalin.MemCached.SockIOPool;
11
12
13
14
15
16
17
18
19
20
21 public class MemcacheCacheStorager<T extends Cacheable> implements
22 CacheStorager<T> {
23
24 private final MemCachedClient mc;
25
26 public MemcacheCacheStorager() {
27 this(new MemcachePoolConfig());
28 }
29
30 public MemcacheCacheStorager(MemcachePoolConfig poolConfig) {
31 mc = new MemCachedClient();
32 poolConfig.initSocketIO();
33 initializeKey();
34 }
35
36 @SuppressWarnings("unchecked")
37 private Set<String> initializeKey() {
38 Set<String> all = (Set<String>) mc.get(ALLKEY);
39 if (all == null) {
40 all = new HashSet<String>();
41 mc.set(ALLKEY, all);
42 }
43 return all;
44 }
45
46 @SuppressWarnings("unchecked")
47 @Override
48 public T lookup(String key) {
49 return (T) mc.get(key);
50 }
51
52 @Override
53 public void caching(String key, T cache) {
54 if (cache.getCreateTime() > 0l) {
55 mc.set(key,
56 cache,
57 new Date(cache.getCreateTime() + cache.getExpires() - CUTMS));
58 } else {
59 mc.set(key, cache);
60 }
61 Set<String> all = initializeKey();
62 all.add(key);
63 mc.set(ALLKEY, all);
64 }
65
66 @Override
67 public T evict(String key) {
68 T cache = lookup(key);
69 mc.delete(key);
70 Set<String> all = initializeKey();
71 all.remove(key);
72 mc.set(ALLKEY, all);
73 return cache;
74 }
75
76 @Override
77 public void clear() {
78 Set<String> all = initializeKey();
79 for (String key : all) {
80 mc.delete(key);
81 }
82 mc.delete(ALLKEY);
83 }
84
85 public static class MemcachePoolConfig {
86 public final static String HOST = "127.0.0.1";
87 public final static int PORT = 11211;
88 public final static int WEIGHT = 1;
89
90 public static int minConn = 5;
91 public static int initConn = 5;
92 public static int maxConn = 100;
93 public static int maxIdle = 300000;
94 public static long maxBusyTime = 30000L;
95 public static int socketTO = 3000;
96 public static int socketConnectTO = 3000;
97 public static boolean failover = true;
98 public static boolean failback = true;
99 public static boolean nagle = false;
100 public static boolean aliveCheck = false;
101 public static final int consistentHash = 3;
102 public static final int mainSleep = 30000;
103
104 private static SockIOPool pool;
105 static {
106 pool = SockIOPool.getInstance();
107 pool.setFailback(failback);
108 pool.setFailover(failover);
109 pool.setMaxBusyTime(maxBusyTime);
110 pool.setMaxConn(maxConn);
111 pool.setMaxIdle(maxIdle);
112 pool.setMinConn(minConn);
113 pool.setNagle(nagle);
114 pool.setSocketConnectTO(socketConnectTO);
115 pool.setSocketTO(socketTO);
116 pool.setAliveCheck(aliveCheck);
117 pool.setHashingAlg(consistentHash);
118 pool.setInitConn(initConn);
119 pool.setMaintSleep(maxBusyTime);
120 }
121
122 private List<MemcacheConfig> configs;
123 private String[] servers;
124 private Integer[] weights;
125
126
127
128
129 public MemcachePoolConfig() {
130 this(HOST, PORT, WEIGHT);
131 }
132
133
134
135
136
137
138
139 public MemcachePoolConfig(String host) {
140 this(host, PORT);
141 }
142
143
144
145
146
147
148
149
150
151 public MemcachePoolConfig(String host, int port) {
152 this(host, port, WEIGHT);
153 }
154
155
156
157
158
159
160
161
162
163
164
165 public MemcachePoolConfig(String host, int port, int weight) {
166 configs = new ArrayList<MemcacheConfig>();
167 configs.add(new MemcacheConfig(host, port, weight));
168 }
169
170 public MemcachePoolConfig addServer(String host) {
171 return addServer(host, PORT, WEIGHT);
172 }
173
174 public MemcachePoolConfig addServer(String host, int port) {
175 return addServer(host, port, WEIGHT);
176 }
177
178 public MemcachePoolConfig addServer(String host, int port, int weight) {
179 configs.add(new MemcacheConfig(host, port, weight));
180 return this;
181 }
182
183 private void initConfig() {
184 if (servers == null || weights == null) {
185 servers = new String[configs.size()];
186 weights = new Integer[configs.size()];
187 for (int i = 0; i < configs.size(); i++) {
188 servers[i] = configs.get(i).getServer();
189 weights[i] = configs.get(i).getWeight();
190 }
191 }
192 }
193
194 private void initSocketIO() {
195 pool.setServers(getServers());
196 pool.setWeights(getWeights());
197 if (pool.isInitialized()) {
198 pool.shutDown();
199 }
200 pool.initialize();
201 }
202
203 public String[] getServers() {
204 initConfig();
205 return servers;
206 }
207
208 public Integer[] getWeights() {
209 initConfig();
210 return weights;
211 }
212
213 @Override
214 public String toString() {
215 return "MemcachePoolConfig [" + configs + "]";
216 }
217
218 private static class MemcacheConfig {
219 private String host;
220 private int port;
221 private int weight;
222
223 public MemcacheConfig(String host, int port, int weight) {
224 this.host = host;
225 this.port = port;
226 this.weight = weight;
227 }
228
229 public String getServer() {
230 return String.format("%s:%d", host, port);
231 }
232
233 public int getWeight() {
234 return weight;
235 }
236
237 @Override
238 public String toString() {
239 return String.format("{%s:%d,%d}", host, port, weight);
240 }
241 }
242 }
243 }