redis——數據結構(整數集合,壓縮列表)

4、整數集合

整數集合(intset)是 Redis 用于保存整數值的集合抽象數據結構, 可以保存?int16_t?、?int32_t?、?int64_t?的整數值, 并且保證集合中不會出現重復元素。

實現較為簡單:

typedef struct intset {// 編碼方式uint32_t encoding;// 集合包含的元素數量uint32_t length;// 保存元素的數組int8_t contents[];
} intset;

各個項在數組中從小到大有序地排列, 并且數組中不包含任何重復項。

雖然?intset?結構將?contents?屬性聲明為?int8_t?類型的數組, 但實際上?contents?數組并不保存任何?int8_t?類型的值 ——?contents?數組的真正類型取決于?encoding?屬性的值:

如果?encoding?屬性的值為?INTSET_ENC_INT16?, 那么?contents?就是一個?int16_t?類型的數組, 數組里的每個項都是一個?int16_t?類型的整數值 (最小值為?-32,768?,最大值為?32,767?)。

如果?encoding?屬性的值為?INTSET_ENC_INT32?, 那么?contents?就是一個?int32_t?類型的數組, 數組里的每個項都是一個?int32_t?類型的整數值 (最小值為?-2,147,483,648?,最大值為?2,147,483,647?)。

如果?encoding?屬性的值為?INTSET_ENC_INT64?, 那么?contents?就是一個?int64_t?類型的數組, 數組里的每個項都是一個?int64_t?類型的整數值 (最小值為?-9,223,372,036,854,775,808?,最大值為?9,223,372,036,854,775,807?)。

? ? 升級

c語言是靜態類型語言,不允許不同類型保存在一個數組。這樣第一,靈活性較差,第二,有時會用掉不必要的內存

比如用long long儲存1

為了提高整數集合的靈活性和節約內存,我們引入升級策略。

當我們要將一個新元素添加到集合里, 并且新元素類型比集合現有元素的類型都要長時, 集合需要先進行升級。

分為三步進行:

  1. 根據新元素的類型, 擴展整數集合底層數組的空間大小, 并為新元素分配空間。
  2. 將底層數組現有的所有元素都轉換成與新元素相同的類型, 并將類型轉換后的元素放置到正確的位上
  3. 將新元素添加到底層數組里面。

因為每次添加新元素都可能會引起升級, 每次升級都要對已有元素類型轉換, 所以添加新元素的時間復雜度為?O(N)?。

因為引發升級的新元素比原數據都長,所以要么他是最大的,要么他是最小的。我們把它放在開頭或結尾即可。

?

? ? 降級

略略略,不管你們信不信,整數集合不支持降級操作。。我也不知道為啥

5、壓縮列表

?

壓縮列表是列表鍵和哈希鍵的底層實現之一。

當一個列表鍵只包含少量列表項,并且列表項都是小整數或者短字符串,redis就會用壓縮列表做列表鍵底層實現。

壓縮列表是 Redis 為了節約內存而開發的, 由一系列特殊編碼的連續內存塊組成的順序型(sequential)數據結構。

一個壓縮列表可以包含任意多個節點(entry), 每個節點可以保存一個字節數組或者一個整數值。

具體實現:

具體說一下entry:

由三個部分組成:

1、previous_entry_length:記錄上一個節點的長度,這樣我們就可以從最后一路遍歷到開頭。

2、encoding:記錄了content所保存的數據類型和長度。(具體編碼不寫了,不重要)

3、content:保存節點值,可以是字節數組或整數。(具體怎么壓縮的等我搞明白再補)

? ? 連鎖更新

前面說過, 每個節點的?previous_entry_length?屬性都記錄了前一個節點的長度:

  • 如果前一節點的長度<?254?KB, 那么?previous_entry_length?需要用?1?字節長的空間
  • 如果前一節點的長度>=254?KB, 那么?previous_entry_length?需要用?5?字節長的空間

現在, 考慮這樣一種情況: 在一個壓縮列表中, 有多個連續的、長度介于?250?字節到?253?字節之間的節點 ,這時, 如果我們將一個長度大于等于?254?字節的新節點?new?設置為壓縮列表的表頭節點。。。。

然后腦補一下,就會導致連鎖擴大每個節點的空間對吧?e(i)因為e(i-1)的擴大而擴大,i+1也是如此,以此類推。。。

?

刪除節點同樣會導致連鎖更新。

這個事情只是想說明一個問題:插入刪除操作的最壞時間復雜度其實是o(n*n),因為每更新一個節點都要o(n)。

但是,也不用太過擔心,因為這種特殊情況并不多見,這些命令的平均復雜度依舊是o(n)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/445413.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445413.shtml
英文地址,請注明出處:http://en.pswp.cn/news/445413.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

原 劍指offer(刷題11-20)--c++,Python版本

文章目錄目錄第11題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第12題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第13 題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第 14題&#xff1a;解題思路&#xff1a;代碼實現&…

LRU介紹和實現

LRU全稱是Least Recently Used&#xff0c;即最近最久未使用的意思。 LRU算法的設計原則是&#xff1a;如果一個數據在最近一段時間沒有被訪問到&#xff0c;那么在將來它被訪問的可能性也很小。也就是說&#xff0c;當限定的空間已存滿數據時&#xff0c;應當把最久沒有被訪問…

機器學習知識總結系列- 知識圖譜(0-0)

文章目錄目錄機器學習知識圖譜目錄 本系列的文章只是根據個人的習慣進行總結&#xff0c;可能結構與一些書籍上不太一樣&#xff0c;開始的內容比較簡單&#xff0c;會隨著后續的深入&#xff0c;不斷豐富和更新圖譜&#xff0c;同時也期待有相同興趣的朋友一起給我留言一起豐富…

跳表介紹和實現

想慢慢的給大家自然的引入跳表。 想想&#xff0c;我們 1&#xff09;在有序數列里搜索一個數 2&#xff09;或者把一個數插入到正確的位置 都怎么做&#xff1f; 很簡單吧 對于第一個操作&#xff0c;我們可以一個一個比較&#xff0c;在數組中我們可以二分&#xff0c;這…

機器學習知識總結系列- 基本概念(1-0)

文章目錄目錄1. 機器學習的定義2. 機器學習的分類2.1根據是否在人類監督下進行訓練監督學習非監督學習半監督學習強化學習2.2根據是否可以動態漸進的學習在線學習批量學習2.3根據是否在訓練數據過程中進行模式識別實例學習基于模型的學習3. 機器學習中的一些常見名詞4. 機器學習…

劍指offer(刷題21-30)--c++,Python版本

文章目錄目錄第 21題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第22 題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第23 題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第24 題&#xff1a;解題思路&#xff1a;代碼實現…

redis——對象

剛寫了redis主要的數據結構&#xff1a; 動態字符串、雙端鏈表、字典、壓縮列表、整數集合、跳表等 redis肯定不能直接使用這些數據結構來實現數據庫&#xff0c;它用這些數據庫建立了一個對象系統&#xff0c;包含&#xff1a; 字符串對象、列表對象、哈希對象、集合對象、…

劍指offer(刷題31-40)--c++,Python版本

文章目錄目錄第31 題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第32題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第33題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第34題&#xff1a;解題思路&#xff1a;代碼實現&a…

redis——數據庫

redis服務器將所有數據庫都保存在redis/redisServer中&#xff0c;數組db存放所有數據庫&#xff0c;每一項是一個redisdb結構。dbnum代表數據庫數量。 客戶端有一個指針指向當前數據庫&#xff0c;可以切換&#xff0c;也就是移動指針。 鍵空間 現在稍微介紹一下redisdb結構…

劍指offer(刷題41-50)--c++,Python版本

文章目錄目錄第41題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第42題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第43題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第44題&#xff1a;解題思路&#xff1a;代碼實現&am…

redis——持久化

因為redis是內存數據庫&#xff0c;他把數據都存在內存里&#xff0c;所以要想辦法實現持久化功能。 RDB RDB持久化可以手動執行&#xff0c;也可以配置定期執行&#xff0c;可以把某個時間的數據狀態保存到RDB文件中&#xff0c;反之&#xff0c;我們可以用RDB文件還原數據庫…

redis原理總結

數據結構&#xff08;字典、鏈表、字符串&#xff09; 數據結構&#xff08;整數集合&#xff0c;壓縮列表&#xff09; 數據結構&#xff08;跳表介紹和手撕&#xff09; LRU介紹和實現 對象&#xff08;字符串對象、列表對象、哈希對象、集合對象、有序集合總結&#xff…

劍指offer(刷題51-60)--c++,Python版本

文章目錄目錄第51題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第52題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第53題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第54題&#xff1a;解題思路&#xff1a;代碼實現&am…

2017第一屆河北省大學生程序設計競賽題解

超級密碼 小明今年9歲了&#xff0c;最近迷上了設計密碼&#xff01;今天&#xff0c;他又設計了一套他認為很復雜的密碼&#xff0c;并且稱之為“超級密碼”. 說實話&#xff0c;這套所謂的“超級密碼”其實并不難&#xff1a;對于一個給定的字符串&#xff0c;你只要提取其中…

劍指offer(刷題61-65)--c++,Python版本

文章目錄目錄第61題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第62題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第63題&#xff1a;解題思路&#xff1a;代碼實現&#xff1a;cpython第64題&#xff1a;解題思路&#xff1a;代碼實現&am…

2018第二屆河北省大學生程序設計競賽題解

icebound的賬單 題目描述 icebound從小就有記賬的習慣。又到了月末icebound統計資金狀況的時候。icebound每個月除了不停的揮霍以外&#xff0c;有時他會良心發現&#xff0c;勤工儉學&#xff0c;因此會有一些微薄的收入。然而icebound數學不好&#xff0c;需要你來幫助他統計…

大數的四則運算(加法、減法、乘法、除法)

大數的四則運算&#xff08;加法、減法、乘法、除法&#xff09; 前言&#xff1a; 在計算機中數字表示的范圍是有限制的&#xff0c;比如我們熟知的 int、float、double 等數據類型所能表示的范圍都是有限的&#xff0c;如果我們要對位數達到幾十位、幾百位、上千位的大整數進…

數組基操三連(1)

題目&#xff1a; 給定一個數組arr&#xff0c;求出需要排序的最短子數組長度 要求&#xff1a; 時間o(n),空間o(1) 思路&#xff1a; 有序的數組中&#xff0c;任意一個數字&#xff0c;一定小于左邊的數大于右邊的數。 我們找到的需要排序的子數組&#xff0c;顯然是比右邊…

IT互聯網公司的筆試的輸入輸出- c++ python

文章目錄目錄c方式1&#xff1a;方式2&#xff1a;Python方式1&#xff1a;方式2&#xff1a;方式3&#xff1a;目錄 c 方式1&#xff1a; 第一種情況&#xff1a;輸入n個數&#xff0c;存放在數組中 #include <iostream> #include <vector> using namespace st…