锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 鐢ㄤ竴涓彲浠?/span>"find reference"鐨?/span>IDE,娌跨潃setex(Set the value and expiration of a key)鍛戒護涓紿ョ┒绔燂細 setGenericCommand鏄竴涓疄鐜?/span>set,setnx,setex鐨勯氱敤鍑芥暟錛屽弬鏁拌緗笉鍚岃屽凡銆?/span> 鍐嶇湅setGenericCommand錛?br /> 13琛屽鐞?/span>"Set the value of a key, only if the key does not exist"鐨勫満鏅紝17琛屾彃鍏ヨ繖涓?/span>key錛?/span>19琛岃緗畠鐨勮秴鏃訛紝娉ㄦ剰鏃墮棿鎴沖凡緇忚璁劇疆鎴愪簡鍒版湡鏃墮棿銆傝繖閲岃鐪嬩竴涓?/span>redisDb(鍗?/span>c->db)鐨勫畾涔夛細 浠呭叧娉?/span>dict鍜?/span>expires錛屽垎鍒潵瀛?/span>key-value鍜屽畠鐨勮秴鏃訛紝涔熷氨鏄濡傛灉涓涓?/span>key-value鏄湁瓚呮椂鐨勶紝閭d箞瀹冧細瀛樺湪dict閲岋紝鍚屾椂涔熷瓨鍒?/span>expires閲岋紝綾諱技榪欐牱鐨勫艦寮忥細dict[key]:value,expires[key]:timeout. 褰撶劧key-value娌℃湁瓚呮椂錛?/span>expires閲屽氨涓嶅瓨鍦ㄨ繖涓?/span>key銆?/span>鍓╀笅setKey鍜?/span>setExpire涓や釜鍑芥暟鏃犻潪鏄彃鏁版嵁鍒頒袱涓瓧鍏擱噷錛岃繖閲屼笉鍐嶈榪般?/span> 閭d箞redis鏄浣曞垹闄よ繃鏈?/span>key鐨勫憿銆?/span> 閫氳繃鏌ョ湅dbDelete鐨勮皟鐢ㄨ咃紝棣栧厛娉ㄦ剰鍒拌繖涓涓嚱鏁幫紝鏄敤鏉ュ垹闄よ繃鏈?/span>key鐨勩?/span> ifNeed琛ㄧず鑳藉垹鍒欏垹錛屾墍浠?/span>4琛屾病鏈夎緗秴鏃朵笉鍒狅紝7琛屽湪"loading"鏃朵笉鍒狅紝16琛岄潪涓誨簱涓嶅垹錛?/span>21琛屾湭鍒版湡涓嶅垹銆?/span>25琛屽悓姝ヤ粠搴撳拰鏂囦歡銆?/span> 鍐嶇湅鐪嬪摢浜涘嚱鏁拌皟鐢ㄤ簡expireIfNeeded錛屾湁lookupKeyRead錛?/span>lookupKeyWrite錛?/span>dbRandomKey錛?/span>existsCommand錛?/span>keysCommand銆傞氳繃榪欎簺鍑芥暟鍛藉悕鍙互鐪嬪嚭錛屽彧瑕佽闂簡鏌愪竴涓?/span>key錛岄『甯﹀仛鐨勪簨鎯呭氨鏄皾璇曟煡鐪嬭繃鏈熷茍鍒犻櫎錛岃繖灝變繚璇佷簡鐢ㄦ埛涓嶅彲鑳借闂埌榪囨湡鐨?/span>key銆備絾鏄鏋滄湁澶ч噺鐨?/span>key榪囨湡錛屽茍涓旀病鏈夎璁塊棶鍒幫紝閭d箞灝辨氮璐逛簡璁稿鍐呭瓨銆?/span>Redis鏄浣曞鐞嗚繖涓棶棰樼殑鍛€?/span> dbDelete鐨勮皟鐢ㄨ呴噷榪樺彂鐜拌繖鏍蜂竴涓嚱鏁幫細 榪欎釜鍑芥暟鐨勬剰鍥懼凡緇忔湁璇存槑錛?/span>鍒犱竴鐐圭偣榪囨湡key錛屽鏋滆繃鏈?/span>key杈冨皯錛岄偅涔熷彧鐢ㄤ竴鐐圭偣cpu銆?/span>25琛岄殢鏈哄彇涓涓?/span>key錛?/span>38琛屽垹key鎴愬姛鐨勬鐜囪緝浣庡氨閫鍑恒傝繖涓嚱鏁拌鏀懼湪涓涓?/span>cron閲岋紝姣忔縐掕璋冪敤涓嬈°傝繖涓畻娉曚繚璇佹瘡嬈′細鍒犻櫎涓瀹氭瘮渚嬬殑key錛屼絾鏄鏋?/span>key鎬婚噺寰堝ぇ錛岃岃繖涓瘮渚嬫帶鍒剁殑澶ぇ錛屽氨闇瑕佹洿澶氭鐨勫驚鐜紝嫻垂cpu錛屾帶鍒剁殑澶皬錛岃繃鏈熺殑key灝變細鍙樺錛屾氮璐瑰唴瀛?#8212;—榪欏氨鏄椂絀烘潈琛′簡銆?/span> 鏈鍚庡湪dbDelete鐨勮皟鐢ㄨ呴噷榪樺彂鐜拌繖鏍蜂竴涓嚱鏁幫細 榪欎釜鍑芥暟澶暱灝變笉鍐嶈榪頒簡錛屾敞閲婇儴鍒嗚鏄庡彧鏈夊湪閰嶇疆鏂囦歡涓緗簡鏈澶у唴瀛樻椂鍊欐墠浼氳皟鐢ㄨ繖涓嚱鏁幫紝鑰岃緗繖涓弬鏁扮殑鎰忎箟鏄紝浣犳妸redis褰撳仛涓涓唴瀛?/span>cache鑰屼笉鏄?/span>key-value鏁版嵁搴撱?/span> 浠ヤ笂3縐嶅垹闄よ繃鏈?/span>key鐨勯斿緞錛岀浜岀瀹氭湡鍒犻櫎涓瀹氭瘮渚嬬殑key鏄富瑕佺殑鍒犻櫎閫斿緞錛岀涓縐?#8220;璇繪椂鍒犻櫎”淇濊瘉榪囨湡key涓嶄細琚闂埌錛岀涓夌鏄竴涓綋鍐呭瓨瓚呭嚭璁懼畾鏃剁殑鏆村姏鎵嬫銆傜敱姝や篃鑳界湅鍑?/span>redis璁捐鐨勫閥濡欎箣澶勶紝 棰樼洰錛氬湪涓涓枃浠朵腑鏈?10G 涓暣鏁幫紝涔卞簭鎺掑垪錛岃姹傛壘鍑轟腑浣嶆暟銆傚唴瀛橀檺鍒朵負 2G銆傚彧鍐欏嚭鎬濊礬鍗沖彲錛堝唴瀛橀檺鍒朵負 2G鐨勬剰鎬濆氨鏄紝鍙互浣跨敤2G鐨勭┖闂存潵榪愯紼嬪簭錛岃屼笉鑰冭檻榪欏彴鏈哄櫒涓婄殑鍏朵粬杞歡鐨勫崰鐢ㄥ唴瀛橈級銆?/p>
鍏充簬涓綅鏁幫細鏁版嵁鎺掑簭鍚庯紝浣嶇疆鍦ㄦ渶涓棿鐨勬暟鍊箋傚嵆灝嗘暟鎹垎鎴愪袱閮ㄥ垎錛屼竴閮ㄥ垎澶т簬璇ユ暟鍊鹼紝涓閮ㄥ垎灝忎簬璇ユ暟鍊箋備腑浣嶆暟鐨勪綅緗細褰撴牱鏈暟涓哄鏁版椂錛屼腑浣嶆暟=(N+1)/2 ; 褰撴牱鏈暟涓哄伓鏁版椂錛屼腑浣嶆暟涓篘/2涓?+N/2鐨勫潎鍊鹼紙閭d箞10G涓暟鐨勪腑浣嶆暟錛屽氨絎?G澶х殑鏁頒笌絎?G+1澶х殑鏁扮殑鍧囧間簡錛夈?/p>
鍒嗘瀽錛氭槑鏄炬槸涓閬撳伐紼嬫у緢寮虹殑棰樼洰錛屽拰涓鑸殑鏌ユ壘涓綅鏁扮殑棰樼洰鏈夊嚑鐐逛笉鍚屻?br>1. 鍘熸暟鎹笉鑳借榪涘唴瀛橈紝涓嶇劧鍙互鐢ㄥ揩閫熼夋嫨錛屽鏋滄暟鐨勮寖鍥村悎閫傜殑璇濊繕鍙互鑰冭檻妗舵帓搴忔垨鑰呰鏁版帓搴忥紝浣嗚繖閲屽亣璁炬槸32浣嶆暣鏁幫紝浠嶆湁4G縐嶅彇鍊鹼紝闇瑕佷竴涓?6G澶у皬鐨勬暟緇勬潵璁℃暟銆?/p>
2. 鑻ョ湅鎴愪粠N涓暟涓壘鍑虹K澶х殑鏁幫紝濡傛灉K涓暟鍙互璇昏繘鍐呭瓨錛屽彲浠ュ埄鐢ㄦ渶灝忔垨鏈澶у爢錛屼絾榪欓噷K=N/2,鏈?G涓暟錛屼粛鐒朵笉鑳借榪涘唴瀛樸?/p>
3. 鎺ヤ笂錛屽浜嶯涓暟鍜孠涓暟閮戒笉鑳戒竴嬈¤榪涘唴瀛樼殑鎯呭喌錛屻婄紪紼嬩箣緹庛嬮噷緇欏嚭涓涓柟妗堬細璁緆<K,涓攌涓暟鍙互瀹屽叏璇昏繘鍐呭瓨錛岄偅涔堝厛鏋勫緩k涓暟鐨勫爢錛屽厛鎵懼嚭絎?鍒発澶х殑鏁幫紝鍐嶆壂鎻忎竴閬嶆暟緇勬壘鍑虹k+1鍒?k鐨勬暟錛屽啀鎵弿鐩村埌鎵懼嚭絎琄涓暟銆傝櫧鐒舵瘡嬈℃椂闂村ぇ綰︽槸nlog(k)錛屼絾闇瑕佹壂鎻廲eil(K/k)嬈★紝榪欓噷瑕佹壂鎻?嬈°?/p>
瑙f硶錛氶鍏堝亣璁炬槸32浣嶆棤絎﹀彿鏁存暟銆?br>1. 璇諱竴閬?0G涓暣鏁幫紝鎶婃暣鏁版槧灝勫埌256M涓尯孌典腑錛岀敤涓涓?4浣嶆棤絎﹀彿鏁存暟緇欐瘡涓浉搴斿尯孌佃鏁般?br>璇存槑錛氭暣鏁拌寖鍥存槸0 - 2^32 - 1錛屼竴鍏辨湁4G縐嶅彇鍊鹼紝鏄犲皠鍒?56M涓尯孌碉紝鍒欐瘡涓尯孌墊湁16錛?G/256M = 16錛夌鍊鹼紝姣?6涓肩畻涓孌碉紝 0锝?5鏄1孌碉紝16锝?1鏄2孌碉紝……2^32-16 锝?^32-1鏄256M孌點備竴涓?4浣嶆棤絎﹀彿鏁存暟鏈澶у兼槸0锝?G-1錛岃繖閲屽厛涓嶈冭檻婧㈠嚭鐨勬儏鍐點傛誨叡鍗犵敤鍐呭瓨256M×8B=2GB銆?/p>
2. 浠庡墠鍒板悗瀵規瘡涓孌電殑璁℃暟绱姞錛屽綋绱姞鐨勫拰瓚呰繃5G鏃跺仠姝紝鎵懼嚭榪欎釜鍖烘錛堝嵆绱姞鍋滄鏃惰揪鍒扮殑鍖烘錛屼篃鏄腑浣嶆暟鎵鍦ㄧ殑鍖烘錛夌殑鏁板艱寖鍥達紝璁句負[a錛宎+15]錛屽悓鏃惰褰曠瘡鍔犲埌鍓嶄竴涓尯孌電殑鎬繪暟錛岃涓簃銆傜劧鍚庯紝閲婃斁闄よ繖涓尯孌靛崰鐢ㄧ殑鍐呭瓨銆?/p>
3. 鍐嶈涓閬?0G涓暣鏁幫紝鎶婂湪[a錛宎+15]鍐呯殑姣忎釜鍊艱鏁幫紝鍗蟲湁16涓鏁般?/p>
4. 瀵規柊鐨勮鏁頒緷嬈$瘡鍔狅紝姣忔鐨勫拰璁句負n錛屽綋m+n鐨勫艱秴榪?G鏃跺仠姝紝姝ゆ椂鐨勮繖涓鏁版墍瀵瑰簲鐨勬暟灝辨槸涓綅鏁般?/p>
鎬葷粨錛?br>1.浠ヤ笂鏂規硶鍙璇諱袱閬嶆暣鏁幫紝瀵規瘡涓暣鏁頒篃鍙槸甯告暟鏃墮棿鐨勬搷浣滐紝鎬諱綋鏉ヨ鏄嚎鎬ф椂闂淬?/p>
2. 鑰冭檻鍏朵粬鎯呭喌銆?br>鑻ユ槸鏈夌鍙風殑鏁存暟錛屽彧闇鏀瑰彉鏄犲皠鍗沖彲銆傝嫢鏄?4涓烘暣鏁幫紝鍒欏鍔犳瘡涓尯孌電殑鑼冨洿錛岄偅涔堝湪絎簩嬈¤鏁版椂錛岃鑰冭檻鏇村鐨勮鏁般傝嫢榪囨煇涓鏁版孩鍑猴紝閭d箞鍙瀹氭墍鍦ㄧ殑鍖烘鎴栦唬琛ㄦ暣鏁頒負鎵姹傦紝榪欓噷鍙渶鍋氬ソ鐩稿簲鐨勫鐞嗐傚櫌錛屽繕浜嗚繕瑕佹壘絎?G+1澶х殑鏁頒簡錛岀浉淇℃湁浜嗕互涓婄殑鎴愭灉錛屾壘鍒拌繖涓暟涔熶笉闅句簡鍚с?/p>
3. 鏃剁┖鏉冭 銆?br>鑺辮垂256涓尯孌典篃璁稿彧鏄伆濂介厤鍚?GB鐨勫唴瀛橈紙鍏跺疄涔熶笉鏄紝鍛靛懙錛夈傚彲浠ュ澶у尯孌佃寖鍥達紝鍑忓皯鍖烘鏁扮洰錛岃妭鐪佷竴浜涘唴瀛橈紝铏界劧澧炲姞絎簩閮ㄥ垎鐨勫鍗曚釜鏁板肩殑璁℃暟錛屼絾絎竴閮ㄥ垎瀵規瘡涓尯孌電殑璁℃暟鍔犲揩浜嗭紙鎬諱綋鏀瑰彉錛燂紵寰呮祴錛夈?/p>
4. 鏄犲皠鏃跺敖閲忕敤浣嶆搷浣滐紝鐢變簬姣忎釜鍖烘鐨勮搗鐐歸兘鏄?鐨勬暣鏁板箓錛屾槧灝勮搗鏉ヤ篃寰堟柟渚褲?br>
c->argv[3] = tryObjectEncoding(c->argv[3]);
setGenericCommand(c,0,c->argv[1],c->argv[3],c->argv[2]);
}
c->argv[2] = tryObjectEncoding(c->argv[2]);
setGenericCommand(c,0,c->argv[1],c->argv[2],NULL);
}
void setnxCommand(redisClient *c) {
c->argv[2] = tryObjectEncoding(c->argv[2]);
setGenericCommand(c,1,c->argv[1],c->argv[2],NULL);
}
void setexCommand(redisClient *c) {
c->argv[3] = tryObjectEncoding(c->argv[3]);
setGenericCommand(c,0,c->argv[1],c->argv[3],c->argv[2]);
}
2 long seconds = 0; /* initialized to avoid an harmness warning */
3
4 if (expire) {
5 if (getLongFromObjectOrReply(c, expire, &seconds, NULL) != REDIS_OK)
6 return;
7 if (seconds <= 0) {
8 addReplyError(c,"invalid expire time in SETEX");
9 return;
10 }
11 }
12
13 if (lookupKeyWrite(c->db,key) != NULL && nx) {
14 addReply(c,shared.czero);
15 return;
16 }
17 setKey(c->db,key,val);
18 server.dirty++;
19 if (expire) setExpire(c->db,key,time(NULL)+seconds);
20 addReply(c, nx ? shared.cone : shared.ok);
21 }
22
dict *dict; /* The keyspace for this DB */
dict *expires; /* Timeout of keys with a timeout set */
dict *blocking_keys; /* Keys with clients waiting for data (BLPOP) */
dict *io_keys; /* Keys with clients waiting for VM I/O */
dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */
int id;
} redisDb;
2 time_t when = getExpire(db,key);
3
4 if (when < 0) return 0; /* No expire for this key */
5
6 /* Don't expire anything while loading. It will be done later. */
7 if (server.loading) return 0;
8
9 /* If we are running in the context of a slave, return ASAP:
10 * the slave key expiration is controlled by the master that will
11 * send us synthesized DEL operations for expired keys.
12 *
13 * Still we try to return the right information to the caller,
14 * that is, 0 if we think the key should be still valid, 1 if
15 * we think the key is expired at this time. */
16 if (server.masterhost != NULL) {
17 return time(NULL) > when;
18 }
19
20 /* Return when this key has not expired */
21 if (time(NULL) <= when) return 0;
22
23 /* Delete the key */
24 server.stat_expiredkeys++;
25 propagateExpire(db,key);
26 return dbDelete(db,key);
27 }
28
2 * will use few CPU cycles if there are few expiring keys, otherwise
3 * it will get more aggressive to avoid that too much memory is used by
4 * keys that can be removed from the keyspace. */
5 void activeExpireCycle(void) {
6 int j;
7
8 for (j = 0; j < server.dbnum; j++) {
9 int expired;
10 redisDb *db = server.db+j;
11
12 /* Continue to expire if at the end of the cycle more than 25%
13 * of the keys were expired. */
14 do {
15 long num = dictSize(db->expires);
16 time_t now = time(NULL);
17
18 expired = 0;
19 if (num > REDIS_EXPIRELOOKUPS_PER_CRON)
20 num = REDIS_EXPIRELOOKUPS_PER_CRON;
21 while (num--) {
22 dictEntry *de;
23 time_t t;
24
25 if ((de = dictGetRandomKey(db->expires)) == NULL) break;
26 t = (time_t) dictGetEntryVal(de);
27 if (now > t) {
28 sds key = dictGetEntryKey(de);
29 robj *keyobj = createStringObject(key,sdslen(key));
30
31 propagateExpire(db,keyobj);
32 dbDelete(db,keyobj);
33 decrRefCount(keyobj);
34 expired++;
35 server.stat_expiredkeys++;
36 }
37 }
38 } while (expired > REDIS_EXPIRELOOKUPS_PER_CRON/4);
39 }
40 }
41
* the max memory used by the server, and we are out of memory.
* This function will try to, in order:
*
* - Free objects from the free list
* - Try to remove keys with an EXPIRE set
*
* It is not possible to free enough memory to reach used-memory < maxmemory
* the server will start refusing commands that will enlarge even more the
* memory usage.
*/
void freeMemoryIfNeeded(void)
]]>
]]>
]]>
鐪嬩簡鍗婂ぉ鐨刡oost::multi_array鏂囨。錛屾墠鍙戠幇鍙互鐢╯hape()[]榪欎釜鐨勪笢瑗匡紝鏉ュ彇鏌愪竴緇寸殑闀垮害
鑰屽叧浜庤鍥鵑儴鍒嗭紝灝忓紵鐪嬬殑涓鐭ュ崐瑙o紝
姣斿錛屾庝箞鏍鋒妸涓涓?×4鐨勭煩闃靛垎鎴?涓?×2鐨勭煩闃靛憿
铏界劧鍙互鐢ㄥ埆鐨勯斿緞瑙e喅錛屼絾榪樻槸鎯崇湅涓媘ulti_array鐨勮鍥炬搷浣?
鏈潵瑕佸疄鐜頒笅Strassen綆楁硶鐨勶紝
涓嬮潰鏄櫘閫氱殑鐭╅樀涔樻硶銆?br>
#include <iostream>
#include "boost/multi_array.hpp"
using namespace std;
typedef boost::multi_array<int, 2> matrix; 
matrix matrix_multiply(matrix& a,matrix& b)

{
matrix::index row=a.shape()[0];
matrix::index col=b.shape()[1];
matrix c(boost::extents[row][col]);
for (matrix::index i=0; i!=a.shape()[0]; ++i)
for (matrix::index j=0; j!=b.shape()[1]; ++j)
for (matrix::index k=0; k!=a.shape()[1]; ++k)
c[i][j]+=a[i][k]*b[k][j];
return c;
}
void print(const matrix& m)

{
for (matrix::index i=0; i!=m.shape()[0]; cout<<endl,++i)
for (matrix::index j=0; j!=m.shape()[1]; ++j)
cout<<m[i][j]<<" ";
}

int main()
{ 

int values[] =
{
0, 1, 2,
3, 4, 5
};
const int values_size = 6;
matrix A(boost::extents[2][3]);
matrix B(boost::extents[3][2]);
A.assign(values,values + values_size);
B.assign(values,values + values_size);
cout<<"matrix A"<<endl;
print(A);
cout<<endl;cout<<"*"<<endl;cout<<"matrix B"<<endl;
print(B);
cout<<endl;cout<<"="<<endl;cout<<"matrix C"<<endl;
print(matrix_multiply(A,B));
cout<<endl; 
return 0;
}
]]>