Update the score of an element inside the sorted set skiplist. * Note that the element must exist and must match 'score'. * This function does not update the score in the hash table side, the * caller should take care of it. * * Note that this function attempts to just update the node, in case after * the score update, the node would be exactly at the same position. * Otherwise the skiplist
| 257 | * |
| 258 | * The function returns the updated element skiplist node pointer. */ |
| 259 | zskiplistNode *zslUpdateScore(zskiplist *zsl, double curscore, sds ele, double newscore) { |
| 260 | zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x; |
| 261 | int i; |
| 262 | |
| 263 | /* We need to seek to element to update to start: this is useful anyway, |
| 264 | * we'll have to update or remove it. */ |
| 265 | x = zsl->header; |
| 266 | for (i = zsl->level-1; i >= 0; i--) { |
| 267 | while (x->level(i)->forward && |
| 268 | (x->level(i)->forward->score < curscore || |
| 269 | (x->level(i)->forward->score == curscore && |
| 270 | sdscmp(x->level(i)->forward->ele,ele) < 0))) |
| 271 | { |
| 272 | x = x->level(i)->forward; |
| 273 | } |
| 274 | update[i] = x; |
| 275 | } |
| 276 | |
| 277 | /* Jump to our element: note that this function assumes that the |
| 278 | * element with the matching score exists. */ |
| 279 | x = x->level(0)->forward; |
| 280 | serverAssert(x && curscore == x->score && sdscmp(x->ele,ele) == 0); |
| 281 | |
| 282 | /* If the node, after the score update, would be still exactly |
| 283 | * at the same position, we can just update the score without |
| 284 | * actually removing and re-inserting the element in the skiplist. */ |
| 285 | if ((x->backward == NULL || x->backward->score < newscore) && |
| 286 | (x->level(0)->forward == NULL || x->level(0)->forward->score > newscore)) |
| 287 | { |
| 288 | x->score = newscore; |
| 289 | return x; |
| 290 | } |
| 291 | |
| 292 | /* No way to reuse the old node: we need to remove and insert a new |
| 293 | * one at a different place. */ |
| 294 | zslDeleteNode(zsl, x, update); |
| 295 | zskiplistNode *newnode = zslInsert(zsl,newscore,x->ele); |
| 296 | /* We reused the old node x->ele SDS string, free the node now |
| 297 | * since zslInsert created a new one. */ |
| 298 | x->ele = NULL; |
| 299 | zslFreeNode(x); |
| 300 | return newnode; |
| 301 | } |
| 302 | |
| 303 | int zslValueGteMin(double value, zrangespec *spec) { |
| 304 | return spec->minex ? (value > spec->min) : (value >= spec->min); |
no test coverage detected