Redis系列(五)底層數據結構之整數集合

前言

Redis 已是你們耳熟能詳的東西了,平常工做也都在使用,面試中也是高頻的會涉及到,那麼咱們對它究竟瞭解有多深入呢?面試

我讀了幾本 Redis 相關的書籍,嘗試去了解它的具體實現,將一些底層的數據結構及實現原理記錄下來。後端

本文將介紹 Redis 中底層的 intset(整數集合) 的實現方法。 它是 Redis 中集合鍵的底層實現之一。數組

2020-01-05-17-31-30

能夠看到圖中,當我給一個 set 中放入了 5 個數字,此時集合的編碼方式是 intset, 而當我放入了一個字符串,編碼方式就變成了 hashtable.微信

定義

intset(整數集合)是 Reids 用於保存整數值的集合抽象數據結構,能夠保存 16,31,64 位的整數且保證不重複。數據結構

它的結構定義爲:學習

typedef struct intset{
    // 編碼方法,指定當前存儲的是 16 位,32 位,仍是 64 位的整數
    int32 encoding;
    // 集合中的元素數量
    int32 length;
    // 保存元素的數組
    int<T> contents;
}
複製代碼
  • encoding 屬性有三種取值,分別表明當前整數集合存儲方式是用 16 位整數數組,32 位整數數組或者 64 位整數數組。
  • length 屬性保存了當前整數集合中有多少個整數。
  • contents 是一個數組,具體是多少位整數的數組,取決 encoding 的值。

2020-01-05-17-48-00

這是一個保存了 5 個整數的 intset 的結構圖。由於存儲的數字都很小,因此 encoding 的值是 16 位的整數。編碼

整數集合的升級

是否是很奇怪,整數集合自己就是來存儲整數的,爲何還須要編碼方式?url

由於在 C 語言裏,整數也是有不少種的。.spa

每當一個整數被添加到整數集合時,都須要先去判斷 這個整數是否大於 當前編碼方式 所能容放的 最大整數, 若是大於,就須要對當前的整數集合進行升級。設計

升級是指什麼呢?假如當前的整數集合中只有一個數字 2. 那麼咱們用 16 位的整數的數組就能夠放下。

當此時進來一個大於 32767(16 位整數的最大值) 的整數,咱們就須要將當前的整數數組升級成一個 32 位整數的數組,同時,要將原來的全部整數轉換成新的編碼。

對於 64 位的升級相似於上面這樣。

整數集合分級的好處

  1. 用能容納數字的最小編碼進行存儲,能夠有效的節約內存。
  2. 整數集合封裝了對三種整數之間的轉換,使用咱們不用考慮類型錯誤,能夠不斷的向整數集合內添加整數。提高了操做的靈活性。

不支持降級

與升級相對應的,當大的數字被刪除以後,整數集合不會進行降級。

總結

整數集合時實現集合鍵的一種數據結構。它以有序數組的實現方式來存儲全部的集合元素。

整數集合內部封裝了對 16 位,32 位,64 位整數的類型轉換,使得整數集合能夠靈活的避免類型錯誤,同時又能夠儘可能的節約內存,減小用大的數據類型裝小的數據的內存浪費。

參考文章

《Redis 的設計與實現(第二版)》

《Redis 深度歷險:核心原理和應用實踐》

完。

聯繫我

最後,歡迎關注個人我的公衆號【 呼延十 】,會不按期更新不少後端工程師的學習筆記。 也歡迎直接公衆號私信或者郵箱聯繫我,必定知無不言,言無不盡。


以上皆爲我的所思所得,若有錯誤歡迎評論區指正。

歡迎轉載,煩請署名並保留原文連接。

聯繫郵箱:huyanshi2580@gmail.com

更多學習筆記見我的博客或關注微信公衆號 < 呼延十 >------>呼延十

相關文章
相關標籤/搜索