当前位置:网站首页>Analyse du code source et de la conception de redis - - 7. Liste rapide
Analyse du code source et de la conception de redis - - 7. Liste rapide
2022-07-23 10:49:00 【Junesfour】
Redis Liste rapide
Catalogue des articles
1. Introduction
Nous avons déjà décrit la structure de la liste liée et la structure de la liste compressée,Ce sont les implémentations sous - jacentes des touches de liste,Mais l'espace supplémentaire de la liste est un peu élevé,Parce queprevEtnextLe pointeur prendra une partie de l'espace(64Occupation du système bit8 + 8 = 16Octets).Et chaque noeud de la liste est attribué individuellement à la mémoire,Peut aggraver la fragmentation de la mémoire.
Donc, dansredis-3.2Début de la version,RedisUtiliserquicklistEn tant qu'implémentation sous - jacente de la clé de liste.
2. quicklistRéalisation
quicklistEn fait, oui.zipListEtlinkedListUn mélange de,Il metzipListMettez - le surlinkedListDans chaque noeud, Réaliser un stockage compact .

2.1 quicklistStructure de l'en - tête
typedef struct quicklist {
// Pointe vers la tête.(À gauche.)quicklistPointeur de noeud
quicklistNode *head;
// Pointe vers la queue(À droite)quicklistPointeur de noeud
quicklistNode *tail;
// ziplistCompteur de noeuds
unsigned long count;
// quicklistCompteur de noeuds
unsigned int len;
// EnregistrerziplistTaille,Configuration du profil,Pourcentage16bits
int fill : 16;
// Degré de compression du noeud ,Configuration du profil,Pourcentage16bits,0Indique qu'il n'y a pas de compression
unsigned int compress : 16;
} quicklist;
Parmi euxfillEtcompress Les propriétés sont configurables ,Inredis.confDans le document.
fillConfiguration correspondant à la propriété :list-max-ziplist-size -2- Quand le nombre est négatif , Signifie ce qui suit :
-1Représente chaquequicklistNodeNodeziplist La taille des octets ne peut pas dépasser4kb.-2Représente chaquequicklistNodeNodeziplist La taille des octets ne peut pas dépasser8kb(Par défaut).-3Représente chaquequicklistNodeNodeziplist La taille des octets ne peut pas dépasser16kb.-4Représente chaquequicklistNodeNodeziplist La taille des octets ne peut pas dépasser32kb.-5Représente chaquequicklistNodeNodeziplist La taille des octets ne peut pas dépasser64kb.
- Quand le nombre est positif , Signifie ce qui suit :
- Représentationziplist La structure peut contenir
entryNombre maximum de,Max.2 ^ 15.
- Représentationziplist La structure peut contenir
compressConfiguration correspondant à la propriété :list-compress-depth 00Indique qu'il n'y a pas de compression(Par défaut).1Représentationquicklist Les deux extrémités de la liste ont1Noeuds non compressés,Compression des noeuds au milieu.2Représentationquicklist Les deux extrémités de la liste ont2Noeuds non compressés,Compression des noeuds au milieu.3Représentationquicklist Les deux extrémités de la liste ont3Noeuds non compressés,Compression des noeuds au milieu.- Max.
2 ^ 16.
- Quand le nombre est négatif , Signifie ce qui suit :
2.2 quicklistStructure des noeuds
typedef struct quicklistNode {
struct quicklistNode *prev; //Pointeur de noeud avant
struct quicklistNode *next; //Pointeur de noeud suivant
// Pointez vers un ziplistStructure, Définir le paramètre de données compressées pour pointer vers quicklistLZFStructure
unsigned char *zl;
// Liste compresséeziplistLongueur totale
unsigned int sz;
// ziplistNombre de noeuds dans,Pourcentage16 bitsLongueur
unsigned int count : 16;
// Indique si LZFAlgorithme de COMPRESSION COMPRESSION COMPRESSIONquicklistNoeud,1 Indique que ,2Indique l'adoption,Pourcentage2 bitsLongueur
unsigned int encoding : 2;
// Représente unquicklistNodeSi le noeud adopteziplistLa structure stocke les données,2Indique l'adoption,1 Indique que ,Par défaut2,Pourcentage2bitsLongueur
unsigned int container : 2;
// Marquagequicklist Compressé ou non ,Pourcentage1bitLongueur
// SirecompressPour1,Attendez d'être comprimé à nouveau
unsigned int recompress : 1;
// À utiliser lors des essais
unsigned int attempted_compress : 1;
// Extension supplémentaire,Pourcentage10bitsLongueur
unsigned int extra : 10;
} quicklistNode;
2.3 Compriméziplist
typedef struct quicklistLZF {
// Indique queLZFAlgorithme compresséziplistTaille
unsigned int sz;
// Enregistrer la compression ziplistTableau de,Tableau flexible
char compressed[];
} quicklistLZF;
2.4 quicklistEntry
// GestionquicklistMoyennequicklistNodeDans les noeudsziplistStructure de l'information
typedef struct quicklistEntry {
// Pointer versquicklistPointeur vers
const quicklist *quicklist;
// Pointer versquicklistNodePointeur de noeud
quicklistNode *node;
// Pointer vers le courantziplistPointeur de structure
unsigned char *zi;
// Pointer vers le courantziplistLa chaîne de la structurevlaueMembres
unsigned char *value;
// Pointer vers le courantziplist Entier de la structure valueMembres
long long longval;
// Enregistrer le courantziplist Taille de la structure en octets
unsigned int sz;
// Enregistrer la relative ziplistOffset of
int offset;
} quicklistEntry;
3. Opérations courantes
3.1 Insérer
quicklist Vous pouvez choisir d'insérer à la tête ou à la queue ,CorrespondantAPI- Oui.quicklistPushHeadEtquicklistPushTail:
int quicklistPushHead(quicklist *quicklist, void *value, size_t sz) {
// Adresse du noeud d'en - tête de sauvegarde
quicklistNode *orig_head = quicklist->head;
// SiziplistPeut être inséréentryNoeud
if (likely(
_quicklistNodeAllowInsert(quicklist->head, quicklist->fill, sz))) {
quicklist->head->zl =
// NoeudpushÀ la tête
ziplistPush(quicklist->head->zl, value, sz, ZIPLIST_HEAD);
// Mise à jourquicklistNodeEnregistrementziplistTaillesz
quicklistNodeUpdateSz(quicklist->head);
} else {
// Si vous ne pouvez pas insérer entryNode toziplist
// Créer un nouveauquicklistNodeNoeud
quicklistNode *node = quicklistCreateNode();
//Oui.entryNoeudpush Au nouveau quicklistNodeDans les noeuds
node->zl = ziplistPush(ziplistNew(), value, sz, ZIPLIST_HEAD);
// Mise à jourziplistTaillesz
quicklistNodeUpdateSz(node);
// Insérer le noeud nouvellement créé avant le noeud d'en - tête
_quicklistInsertNodeBefore(quicklist, quicklist->head, node);
}
// Mise à jourquicklistNodeCompteur
quicklist->count++;
// Mise à jourentryCompteur
quicklist->head->count++;
// Si vous changez le pointeur du noeud de tête, retournez 1,Sinon, retournez à0
return (orig_head != quicklist->head);
}
int quicklistPushTail(quicklist *quicklist, void *value, size_t sz) {
quicklistNode *orig_tail = quicklist->tail;
// SiziplistPeut être inséréentryNoeud
if (likely(
_quicklistNodeAllowInsert(quicklist->tail, quicklist->fill, sz))) {
quicklist->tail->zl =
// NoeudpushÀ la queue
ziplistPush(quicklist->tail->zl, value, sz, ZIPLIST_TAIL);
// Mise à jourquicklistNodeEnregistrementziplistTaillesz
quicklistNodeUpdateSz(quicklist->tail);
} else {
// Créer un nouveauquicklistNodeNoeud
quicklistNode *node = quicklistCreateNode();
// Oui.entryNoeudpush Au nouveau quicklistNodeDans les noeuds
node->zl = ziplistPush(ziplistNew(), value, sz, ZIPLIST_TAIL);
// Mise à jourziplistTaillesz
quicklistNodeUpdateSz(node);
// Après avoir inséré le noeud nouvellement créé dans le noeud de queue
_quicklistInsertNodeAfter(quicklist, quicklist->tail, node);
}
// Mise à jourquicklistNodeCompteur
quicklist->count++;
// Mise à jourentryCompteur
quicklist->tail->count++;
// Si vous changez le pointeur du noeud de queue, retournez 1,Sinon, retournez à0
return (orig_tail != quicklist->tail);
}
Références:
《RedisConception et mise en œuvre》
边栏推荐
- ROS2的topic pub 指令出现:Failed to populate field: ‘Vector3‘ object has no attribute ‘x:1‘错误
- Chapter 4 Executing Commands
- 优化.NET 应用程序 CPU 和内存的11 个实践
- Mysql数据库基础
- 0基础转行软件测试,月薪6000和11000的必备技能,截然不同...
- LeetCode刷题--点滴记录022
- 12 个适合做外包项目的开源后台管理系统
- 第12届 蓝桥杯 嵌入式设计与开发项目
- Script of Nacos current limiting query
- Comprehensive experiment of realizing private network interworking under mGRE environment
猜你喜欢

12 open source background management systems suitable for outsourcing projects

Redis源码与设计剖析 -- 13.有序集合对象

海德堡CP2000电路板维修印刷机主机控制器操作及保养注意事项

PyQt5_ Pyqtgraph mouse draws line segments on the line graph

04_ue4进阶_物理碰撞入门和发射火球

优化.NET 应用程序 CPU 和内存的11 个实践

SQLZOO——SELECT from WORLD Tutorial

【视觉SLAM】ORB-SLAM: Tracking and Mapping Recognizable Features

Custom events in components

Mysql数据库基础
随机推荐
3dMax先蒙皮刷权重,再附加合并
SQLZOO——SELECT from WORLD Tutorial
PXE remote installation and kickstart unattended installation technical documents
Cloudcompare & PCL point cloud point matching (based on point to face distance)
SVG, canvas, drawing line segments and filling polygon, rectangle, curve drawing and filling
Jmeter-记一次自动化造数引发的BeanShell写入excel实例
MySQL index operation
Openvino Datawhale
Global event bus
Redis源码与设计剖析 -- 5.整数集合
Wechat applet package wx.request
Meituan's 8-year experience on how to improve test engineers (automation, performance, test development)
TS类型体操 之 中级类型体操挑战收官之战
C# 客户端程序调用外部程序的3种实现方法
20.有效的括号
Kubernetes技术与架构(六)
Redis源码与设计剖析 -- 10.列表对象
Chapter2 Standard Output
R语言使用DALEX包对h2o包构建的机器学习模型进行解释分析:总结及实战
[warning] recognizing corrupt image/label during yolov5 training: [errno 2]...... it is impossible to complete the training data set. I will take you to solve it quickly