00001
00090 #ifndef INCLUDED_MemCacheClient
00091 #define INCLUDED_MemCacheClient
00092
00093 #ifndef WIN32
00094 # include <stdint.h>
00095 #endif
00096
00097 #include <string>
00098 #include <vector>
00099
00100 #include "ReadWriteBuffer.h"
00101
00102
00108 enum MCResult {
00109
00110 MCERR_OK = 0,
00111 MCERR_NOREPLY = 1,
00112 MCERR_NOTSTORED = 2,
00113 MCERR_NOTFOUND = 3,
00114
00115
00116 MCERR_NOSERVER = -1
00117 };
00118
00119
00127 class MemCacheClient
00128 {
00129 class Server;
00130
00131 public:
00132 typedef std::string string_t;
00133 #ifdef WIN32
00134 typedef unsigned __int64 uint64_t;
00135 #else
00136 typedef unsigned long long uint64_t;
00137 #endif
00138
00140 struct MemRequest
00141 {
00142 struct Sort;
00143 Server * mServer;
00144
00145 public:
00147 MemRequest() { Clear(); }
00148
00150 void Clear() {
00151 mServer = NULL;
00152 mKey = "";
00153 mFlags = 0;
00154 mExpiry = 0;
00155 mCas = 0;
00156 mResult = MCERR_OK;
00157 mData.SetEmpty();
00158 }
00159
00160 public:
00166 string_t mKey;
00167
00173 unsigned int mFlags;
00174
00181 time_t mExpiry;
00182
00184 uint64_t mCas;
00185
00192 MCResult mResult;
00193
00197 ReadWriteBuffer mData;
00198 };
00199
00200 public:
00202 const static int MAX_REQUESTS = 20;
00203
00205 MemCacheClient();
00206
00208 MemCacheClient(const MemCacheClient &);
00209
00215 MemCacheClient & operator=(const MemCacheClient &);
00216
00221 ~MemCacheClient();
00222
00229 void SetTimeout(int a_nTimeoutMs);
00230
00231
00246 bool AddServer(const char * a_pszServer);
00247
00257 bool DelServer(const char * a_pszServer);
00258
00263 void GetServers(std::vector<string_t> & a_rgServers);
00264
00266 void ClearServers();
00267
00268
00279 inline int Add(MemRequest & a_oItem) { return Store("add", &a_oItem, 1); }
00280
00289 inline int Set(MemRequest & a_oItem) { return Store("set", &a_oItem, 1); }
00290
00298 inline int Replace(MemRequest & a_oItem) { return Store("replace", &a_oItem, 1); }
00299
00305 inline int Append(MemRequest & a_oItem) { return Store("append", &a_oItem, 1); }
00306
00312 inline int Prepend(MemRequest & a_oItem) { return Store("prepend", &a_oItem, 1); }
00313
00323 inline int CheckSet(MemRequest & a_oItem) { return Store("cas", &a_oItem, 1); }
00324
00330 inline int Get(MemRequest & a_oItem) { return Combine("get", &a_oItem, 1); }
00331
00337 inline int Gets(MemRequest & a_oItem) { return Combine("gets", &a_oItem, 1); }
00338
00344 inline int Del(MemRequest & a_oItem) { return Combine("del", &a_oItem, 1); }
00345
00346
00360 inline MCResult Increment(const char * a_pszKey, uint64_t * a_pnNewValue = NULL, uint64_t a_nDiff = 1, bool a_bWantReply = true) {
00361 return IncDec("incr", a_pszKey, a_pnNewValue, a_nDiff, a_bWantReply);
00362 }
00363
00377 inline MCResult Decrement(const char * a_pszKey, uint64_t * a_pnNewValue = NULL, uint64_t a_nDiff = 1, bool a_bWantReply = true) {
00378 return IncDec("decr", a_pszKey, a_pnNewValue, a_nDiff, a_bWantReply);
00379 }
00380
00381
00396 inline int Add(MemRequest * a_rgItem, int a_nCount) { return Store("add", a_rgItem, a_nCount); }
00397
00409 inline int Set(MemRequest * a_rgItem, int a_nCount) { return Store("set", a_rgItem, a_nCount); }
00410
00422 inline int Replace(MemRequest * a_rgItem, int a_nCount) { return Store("replace", a_rgItem, a_nCount); }
00423
00433 inline int Append(MemRequest * a_rgItem, int a_nCount) { return Store("append", a_rgItem, a_nCount); }
00434
00444 inline int Prepend(MemRequest * a_rgItem, int a_nCount) { return Store("prepend", a_rgItem, a_nCount); }
00445
00459 inline int CheckSet(MemRequest * a_rgItem, int a_nCount) { return Store("cas", a_rgItem, a_nCount); }
00460
00470 inline int Get(MemRequest * a_rgItem, int a_nCount) { return Combine("get", a_rgItem, a_nCount); }
00471
00481 inline int Gets(MemRequest * a_rgItem, int a_nCount) { return Combine("gets", a_rgItem, a_nCount); }
00482
00492 inline int Del(MemRequest * a_rgItem, int a_nCount) { return Combine("del", a_rgItem, a_nCount); }
00493
00505 int FlushAll(const char * a_pszServer = NULL, int a_nExpiry = 0);
00506
00509 private:
00510
00516 std::vector<Server*> m_rgpServer;
00517
00518 int m_nTimeoutMs;
00519
00526 struct ConsistentHash {
00527 unsigned long mHash;
00528 Server * mServer;
00529
00531 ConsistentHash(unsigned long aHash, Server * aServer)
00532 : mHash(aHash), mServer(aServer) { }
00534 ConsistentHash(const ConsistentHash & rhs) { operator=(rhs); }
00536 ConsistentHash & operator=(const ConsistentHash & rhs) {
00537 mHash = rhs.mHash; mServer = rhs.mServer; return *this; }
00539 bool operator<(const ConsistentHash & rhs) const { return mHash < rhs.mHash; }
00541 bool operator==(const ConsistentHash & rhs) const { return mHash == rhs.mHash; }
00543 struct MatchServer;
00544 };
00545
00550 std::vector<ConsistentHash> m_rgServerHash;
00551
00553 unsigned long CreateKeyHash(const char * a_pszKey);
00554
00556 Server * FindServer(const string_t & a_sKey);
00557
00559 int Store(const char * a_pszType, MemRequest * a_rgItem, int a_nCount);
00560
00562 void HandleStoreResponse(Server * a_pServer, MemRequest & a_oItem);
00563
00565 int Combine(const char * a_pszType, MemRequest * a_rgItem, int a_nCount);
00566
00568 int HandleGetResponse(Server * a_pServer, MemRequest ** a_ppBegin, MemRequest ** a_ppEnd);
00569
00571 int HandleDelResponse(Server * a_pServer, MemRequest ** a_ppBegin, MemRequest ** a_ppEnd);
00572
00574 MCResult IncDec(const char * a_pszType, const char * a_pszKey, uint64_t * a_pnNewValue, uint64_t a_nDiff, bool a_bWantReply);
00575
00577 };
00578
00579 #endif // INCLUDED_MemCacheClient