MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / zslInsert

Function zslInsert

src/t_zset.cpp:132–187  ·  view source on GitHub ↗

Insert a new node in the skiplist. Assumes the element does not already * exist (up to the caller to enforce that). The skiplist takes ownership * of the passed SDS string 'ele'. */

Source from the content-addressed store, hash-verified

130 * exist (up to the caller to enforce that). The skiplist takes ownership
131 * of the passed SDS string 'ele'. */
132zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {
133 zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
134 unsigned int rank[ZSKIPLIST_MAXLEVEL];
135 int i, level;
136
137 serverAssert(!std::isnan(score));
138 x = zsl->header;
139 for (i = zsl->level-1; i >= 0; i--) {
140 /* store rank that is crossed to reach the insert position */
141 rank[i] = i == (zsl->level-1) ? 0 : rank[i+1];
142 while (x->level(i)->forward &&
143 (x->level(i)->forward->score < score ||
144 (x->level(i)->forward->score == score &&
145 sdscmp(x->level(i)->forward->ele,ele) < 0)))
146 {
147 rank[i] += x->level(i)->span;
148 x = x->level(i)->forward;
149 }
150 update[i] = x;
151 }
152 /* we assume the element is not already inside, since we allow duplicated
153 * scores, reinserting the same element should never happen since the
154 * caller of zslInsert() should test in the hash table if the element is
155 * already inside or not. */
156 level = zslRandomLevel();
157 if (level > zsl->level) {
158 for (i = zsl->level; i < level; i++) {
159 rank[i] = 0;
160 update[i] = zsl->header;
161 update[i]->level(i)->span = zsl->length;
162 }
163 zsl->level = level;
164 }
165 x = zslCreateNode(level,score,ele);
166 for (i = 0; i < level; i++) {
167 x->level(i)->forward = update[i]->level(i)->forward;
168 update[i]->level(i)->forward = x;
169
170 /* update span covered by update[i] as x is inserted here */
171 x->level(i)->span = update[i]->level(i)->span - (rank[0] - rank[i]);
172 update[i]->level(i)->span = (rank[0] - rank[i]) + 1;
173 }
174
175 /* increment span for untouched levels */
176 for (i = level; i < zsl->level; i++) {
177 update[i]->level(i)->span++;
178 }
179
180 x->backward = (update[0] == zsl->header) ? NULL : update[0];
181 if (x->level(0)->forward)
182 x->level(0)->forward->backward = x;
183 else
184 zsl->tail = x;
185 zsl->length++;
186 return x;
187}
188
189/* Internal function used by zslDelete, zslDeleteRangeByScore and

Callers 9

rdbLoadObjectFunction · 0.85
georadiusGenericFunction · 0.85
zslUpdateScoreFunction · 0.85
zsetConvertFunction · 0.85
zsetAddFunction · 0.85
zsetDupFunction · 0.85
zdiffAlgorithm1Function · 0.85
zdiffAlgorithm2Function · 0.85

Calls 4

sdscmpFunction · 0.85
zslRandomLevelFunction · 0.85
zslCreateNodeFunction · 0.85
levelMethod · 0.80

Tested by

no test coverage detected