redis資料結構原始碼閱讀——字串編碼過程
redis資料結構原始碼閱讀——字串編碼過程
對於RAW
型別的字串,需要進一步進行編碼,判斷它是不是可以表示為整型數;更進一步地,看它能否成為共享變數。當然這都是為了節約記憶體。
/* Try to encode a string object in order to save space */
robj *tryObjectEncoding(robj *o) {
long value;
sds s = o->ptr;
size_t len;
1. 判斷是不是能編碼
/* 確保這是一個字串物件,
* 這是我們在這個函式中編碼的唯一型別。
* 其他型別使用編碼的高效記憶體表示,但由實現該型別的命令處理。 */
// 判斷是不是字串物件
redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);
// 判斷它的編碼型別
if (!sdsEncodedObject(o)) return o;
// 判斷它是不是共享物件,引用數是不是大於 1
if (o->refcount > 1) return o;
2. 判斷是不是能編碼為INT
型
/* 檢查是否可以把這個字串表示成一個長整數。
* 請注意,大於21字元的字串是不可表示為32位或64位整數的。 */
len = sdslen(s);
// string2l: string 物件轉 long 物件的函式
if (len <= 21 && string2l(s,len,&value)) {
/* 此物件可編碼為long物件。嘗試使用共享物件。
* 注意,當使用 maxmemory 時,我們避免使用共享整數,
* 因為每個物件都需要有一個私有的LRU欄位,以便LRU演算法正常工作。 */
if ((server.maxmemory == 0 ||
(server.maxmemory_policy != REDIS_MAXMEMORY_VOLATILE_LRU &&
server.maxmemory_policy != REDIS_MAXMEMORY_ALLKEYS_LRU)) &&
value >= 0 &&
value < REDIS_SHARED_INTEGERS)
{
// 釋放原來的 string 物件
decrRefCount(o);
// 新增新的全域性 long 型別引用
incrRefCount(shared.integers[value]);
return shared.integers[value];
} else {
// 把物件型別從 string 轉為 int
if (o->encoding == REDIS_ENCODING_RAW) sdsfree(o->ptr);
o->encoding = REDIS_ENCODING_INT;
o->ptr = (void*) value;
return o;
}
}
3. 判斷是不是能編碼為EMBSTR
/* 如果字串很小,仍然是原始編碼,
* 那麼嘗試EMBSTR編碼,它更有效。
* 在這種表示中,物件和SDS字串在相同的記憶體塊中分配,
* 以節省空間和快取丟失。 */
if (len <= REDIS_ENCODING_EMBSTR_SIZE_LIMIT) {
robj *emb;
if (o->encoding == REDIS_ENCODING_EMBSTR) return o;
emb = createEmbeddedStringObject(s,sdslen(s));
decrRefCount(o);
return emb;
}
4. 沒法編碼釋放其他空間
/* We can't encode the object...
*
* Do the last try, and at least optimize the SDS string inside
* the string object to require little space, in case there
* is more than 10% of free space at the end of the SDS string.
*
* We do that only for relatively large strings as this branch
* is only entered if the length of the string is greater than
* REDIS_ENCODING_EMBSTR_SIZE_LIMIT. */
if (o->encoding == REDIS_ENCODING_RAW &&
sdsavail(s) > len/10)
{
o->ptr = sdsRemoveFreeSpace(o->ptr);
}
/* Return the original object. */
return o;
}
相關文章
- Redis原始碼閱讀:Redis字串SDSRedis原始碼字串
- Redis原始碼閱讀:sds字串實現Redis原始碼字串
- Redis 資料結構之字串的那些騷操作 -- 像讀小說一樣讀原始碼Redis資料結構字串原始碼
- Tomcat聯結器執行過程(原始碼閱讀)Tomcat原始碼
- [Redis原始碼閱讀]redis持久化Redis原始碼持久化
- redis 資料結構和內部編碼Redis資料結構
- Redis資料結構的內部編碼Redis資料結構
- spring原始碼閱讀--容器啟動過程Spring原始碼
- SOFAJRaft原始碼閱讀-模組啟動過程Raft原始碼
- Redis資料結構概覽(原始碼分析)Redis資料結構原始碼
- 【原始碼閱讀】AndPermission原始碼閱讀原始碼
- Android原始碼閱讀-編譯8.0原始碼Android原始碼編譯
- 【redis】-- 資料結構及底層編碼篇Redis資料結構
- Magic原始碼閱讀(三)——資料匯入和構建原始碼
- TiCDC 原始碼閱讀(三)TiCDC 叢集工作過程解析原始碼
- zk原始碼閱讀9:資料模型ACL之基礎資料結構以及驗證原始碼模型資料結構
- Redis 資料結構與物件編碼 (Object Encoding)Redis資料結構物件ObjectEncoding
- Vue原始碼閱讀--過濾器Vue原始碼過濾器
- Redis原始碼分析-底層資料結構盤點Redis原始碼資料結構
- goroutine排程原始碼閱讀筆記Go原始碼筆記
- ConcurrentHashMap 原始碼閱讀小結HashMap原始碼
- [PY3]——內建資料結構(5)——字串編碼資料結構字串編碼
- [Redis原始碼閱讀]實現一個redis命令--nonzerodecrRedis原始碼
- 【原始碼】Redis Server啟動過程原始碼RedisServer
- 【原始碼】Redis命令處理過程原始碼Redis
- [Redis原始碼閱讀]dict字典的實現Redis原始碼
- 見微知著——Redis字串內部結構原始碼分析Redis字串原始碼
- 【原始碼閱讀】Glide原始碼閱讀之with方法(一)原始碼IDE
- 【原始碼閱讀】Glide原始碼閱讀之into方法(三)原始碼IDE
- 跟著大彬讀原始碼 - Redis 7 - 物件編碼之簡單動態字串原始碼Redis物件字串
- Redis原始碼學習——基礎資料結構之SDSRedis原始碼資料結構
- jQuery原始碼閱讀1—jQuery架構jQuery原始碼架構
- 使用 SourceInsight 閱讀、編輯原始碼原始碼
- Redis 字串 內部資料結構Redis字串資料結構
- 走近原始碼:Redis的啟動過程原始碼Redis
- Spring 6 原始碼編譯和高效閱讀原始碼技巧分享Spring原始碼編譯
- ReactorKit原始碼閱讀React原始碼
- AQS原始碼閱讀AQS原始碼