typedef struct intestintest
那麼在整數集合怎麼保證它的有序性?它根據的是陣列的插入排序,先確定好位置,然後插進去,後邊的元素後移。
在整數集合中可以儲存int_16,int_32,int_64的整數那在整數集合中怎樣處理這幾種整數型別之間的關係呢?假設陣列中的最大值為x。
那如果我在集合中加了超過此編碼方式的極限呢?比如:本來是16位,但是我要存100000,因此就有了下邊的公升級操作了。當我們要新增乙個新元素並且新元素的值大於或小於當前的所能訪問值的極限,因此,在存之前內部要對整數集合進行公升級,然後將我們的值存進去。
公升級的步驟:
根據新元素型別,擴充套件空間,並為新元素分配空間
將其餘數也換位該元素型別,並維持底層有序性
將新元素加到陣列裡
公升級的好處:
節約空間
提公升整數集合的靈活性(隨意新增元素不怕型別有誤,內部會自動轉型別)
那公升級了,然後我把超出極限的元素移出來了,是不是能降級了?整數集合不支援降級操作,公升級後就一直儲存這種編碼方式,除非再次公升級。就和我們玩的象棋裡的士兵一樣。
struct ziplist
struct entry
那如果由乙個這樣的情況 : 在壓縮列表由多個長度介於250-253的節點,我們要在表頭節點插入乙個新的節點(比較大的),但是它後乙個節點的previous_entry_length用乙個位元組儲存不了,因此它會採用五個位元組來儲存,因此新節點的後乙個節點占用的位元組數就增多為254以上,然後又很巧合這個節點的下乙個節點長度也是介於250-253,然後它也增多為254以上,然後導致它後邊節點的位元組變化。這個就是連鎖更新問題。程式需要對壓縮列表不斷的進行重分配操作。當然,上邊的情況只是連鎖更新的一種,刪除節點也同樣會發生連鎖更新問題。
比如是在乙個small節點(小於254),它的前邊是乙個big節點(大於254),然後在small節點後都是介於250-253大小的節點,當我們刪除small節點時,就會引起後邊節點的儲存空間變化,也同樣會導致連鎖更新。那連鎖更新會不會讓我們的效能很低下,那為什麼redis還要使用這種資料結構呢?
雖然有連鎖更新,但是如上邊案例的事件發生率很小,要連續多個介於250-253大小的節點的概率很小,就算有的話,不是特別多也能很快的解決,不會影響效率。
Redis設計與實現(四) 事務
redis也提供事務機制來滿足acid性質。事務的整個過程會經歷三個階段 事務開始 multi命令標誌著事務的開始。命令入隊 如果客戶端傳送的是exec discard watch multi四個命令,那麼就會立即執行,其他的命令只會放入事務佇列中等待執行。事務執行 當伺服器接收到了exec命令之後...
Redis設計與實現 四 跳躍表
跳躍表是乙個有序的資料結構,跳躍是通過在當前節點儲存多個其他節點的指標,來達到跳躍的目的。它支援平均o logn 最差o n 複雜度的節點查詢,還可以通過順序性來批量處理節點。在大部分情況下,跳躍表的效率和平衡樹是一樣的,但是邏輯上比平衡樹更加簡單。redis通過跳躍表實現有序集合鍵的底層實現之一。...
Redis 設計與實現
本書的目標是以簡明易懂的方式講解 redis 的內部執行機制,通過閱讀本書,你可以了解到 redis 從資料結構到伺服器構造在內的幾乎所有知識。為了保證內容的簡潔性,本書會盡量以高抽象層次的角度來觀察 redis 並將 的細節留給讀者自己去考究。如果讀者只是對 redis 的內部運作機制感興趣,但並...