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

Function zsetAdd

src/t_zset.cpp:1324–1454  ·  view source on GitHub ↗

Add a new element or update the score of an existing element in a sorted * set, regardless of its encoding. * * The set of flags change the command behavior. * * The input flags are the following: * * ZADD_INCR: Increment the current element score by 'score' instead of updating * the current element score. If the element does not exist, we * assume 0 as previous sco

Source from the content-addressed store, hash-verified

1322 * The function does not take ownership of the 'ele' SDS string, but copies
1323 * it if needed. */
1324int zsetAdd(robj *zobj, double score, sds ele, int in_flags, int *out_flags, double *newscore) {
1325 /* Turn options into simple to check vars. */
1326 int incr = (in_flags & ZADD_IN_INCR) != 0;
1327 int nx = (in_flags & ZADD_IN_NX) != 0;
1328 int xx = (in_flags & ZADD_IN_XX) != 0;
1329 int gt = (in_flags & ZADD_IN_GT) != 0;
1330 int lt = (in_flags & ZADD_IN_LT) != 0;
1331 *out_flags = 0; /* We'll return our response flags. */
1332 double curscore;
1333
1334 /* NaN as input is an error regardless of all the other parameters. */
1335 if (std::isnan(score)) {
1336 *out_flags = ZADD_OUT_NAN;
1337 return 0;
1338 }
1339
1340 /* Update the sorted set according to its encoding. */
1341 if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
1342 unsigned char *eptr;
1343
1344 if ((eptr = zzlFind((unsigned char*)zobj->m_ptr,ele,&curscore)) != NULL) {
1345 /* NX? Return, same element already exists. */
1346 if (nx) {
1347 *out_flags |= ZADD_OUT_NOP;
1348 return 1;
1349 }
1350
1351 /* Prepare the score for the increment if needed. */
1352 if (incr) {
1353 score += curscore;
1354 if (std::isnan(score)) {
1355 *out_flags |= ZADD_OUT_NAN;
1356 return 0;
1357 }
1358 }
1359
1360 /* GT/LT? Only update if score is greater/less than current. */
1361 if ((lt && score >= curscore) || (gt && score <= curscore)) {
1362 *out_flags |= ZADD_OUT_NOP;
1363 return 1;
1364 }
1365
1366 if (newscore) *newscore = score;
1367
1368 /* Remove and re-insert when score changed. */
1369 if (score != curscore) {
1370 zobj->m_ptr = zzlDelete((unsigned char*)zobj->m_ptr,eptr);
1371 zobj->m_ptr = zzlInsert((unsigned char*)zobj->m_ptr,ele,score);
1372 *out_flags |= ZADD_OUT_UPDATED;
1373 }
1374 return 1;
1375 } else if (!xx) {
1376 /* check if the element is too large or the list
1377 * becomes too long *before* executing zzlInsert. */
1378 if (zzlLength((unsigned char*)ptrFromObj(zobj))+1 > g_pserver->zset_max_ziplist_entries ||
1379 sdslen(ele) > g_pserver->zset_max_ziplist_value ||
1380 !ziplistSafeToAdd((unsigned char *)ptrFromObj(zobj), sdslen(ele)))
1381 {

Callers 5

zaddGenericCommandFunction · 0.85
RM_ZsetAddFunction · 0.85
RM_ZsetIncrbyFunction · 0.85

Calls 13

zzlFindFunction · 0.85
zzlDeleteFunction · 0.85
zzlInsertFunction · 0.85
zzlLengthFunction · 0.85
ptrFromObjFunction · 0.85
sdslenFunction · 0.85
ziplistSafeToAddFunction · 0.85
zsetConvertFunction · 0.85
zslUpdateScoreFunction · 0.85
sdsdupFunction · 0.85
zslInsertFunction · 0.85
dictFindFunction · 0.70

Tested by

no test coverage detected