|
77 | 77 | * compile time constants. |
78 | 78 | * |
79 | 79 | * This is still in the beta stage and has some limitations: |
80 | | - * - Large values may cause overflows ( > 512 bytes) |
81 | 80 | * - Limited command support due to parser limitations: |
82 | 81 | * - Sorted sets and lists need optional command parsing support. |
83 | 82 | * - Repairing on the read path vs. the background has perf implications. In the future, |
|
290 | 289 | "local value = redis.call(orig_cmd, key, field)\n"\ |
291 | 290 | "return {status_field, ts, value}\n\r\n" |
292 | 291 |
|
| 292 | +#define ZADD_SCRIPT "$4\r\nEVAL\r\n$2022\r\n"\ |
| 293 | + "local key = KEYS[1]\n"\ |
| 294 | + "local top_level_add_set = KEYS[2]\n"\ |
| 295 | + "local top_level_rem_set = KEYS[3]\n"\ |
| 296 | + "local add_set = top_level_add_set .. '_' .. key\n"\ |
| 297 | + "local rem_set = top_level_rem_set .. '_' .. key\n"\ |
| 298 | + "local orig_cmd = ARGV[1]\n"\ |
| 299 | + "local num_opts = ARGV[2]\n"\ |
| 300 | + "local num_fields = ARGV[3]\n"\ |
| 301 | + "local cur_ts = ARGV[4]\n"\ |
| 302 | + "local start_loop = 5 + num_opts\n"\ |
| 303 | + "local end_loop = (num_fields * 2) + 4 + num_opts\n"\ |
| 304 | + "local top_level_rem_set_ts = redis.call('ZSCORE', top_level_rem_set, key)\n"\ |
| 305 | + "if (top_level_rem_set_ts) then\n"\ |
| 306 | + " if (tonumber(cur_ts) < tonumber(top_level_rem_set_ts)) then\n"\ |
| 307 | + " return 0\n"\ |
| 308 | + " end\n"\ |
| 309 | + " redis.call('ZREM', top_level_rem_set, key)\n"\ |
| 310 | + "end\n"\ |
| 311 | + "local top_level_add_set_ts = redis.call('ZSCORE', top_level_add_set, key)\n"\ |
| 312 | + "if (top_level_add_set_ts) then\n"\ |
| 313 | + " if (tonumber(cur_ts) > tonumber(top_level_add_set_ts)) then\n"\ |
| 314 | + " redis.call('ZADD', top_level_add_set, cur_ts, key)\n"\ |
| 315 | + " end\n"\ |
| 316 | + "else\n"\ |
| 317 | + " redis.call('ZADD', top_level_add_set, cur_ts, key)\n"\ |
| 318 | + "end\n"\ |
| 319 | + "local skiploop\n"\ |
| 320 | + "local ret\n"\ |
| 321 | + "for i=start_loop,end_loop,2\n"\ |
| 322 | + "do\n"\ |
| 323 | + " skiploop = false\n"\ |
| 324 | + " local field = ARGV[i]\n"\ |
| 325 | + " local value = ARGV[i+1]\n"\ |
| 326 | + " local last_seen_ts_in_add = redis.call('ZSCORE', add_set, field)\n"\ |
| 327 | + " local last_seen_ts_in_rem = redis.call('ZSCORE', rem_set, field)\n"\ |
| 328 | + " if (last_seen_ts_in_rem) then\n"\ |
| 329 | + " if (tonumber(cur_ts) < tonumber(last_seen_ts_in_rem)) then\n"\ |
| 330 | + " skiploop = true\n"\ |
| 331 | + " end\n"\ |
| 332 | + " redis.call('ZREM', rem_set, field)\n"\ |
| 333 | + " elseif (last_seen_ts_in_add) then\n"\ |
| 334 | + " if (tonumber(cur_ts) < tonumber(last_seen_ts_in_add)) then\n"\ |
| 335 | + " skiploop = true\n"\ |
| 336 | + " end\n"\ |
| 337 | + " end\n"\ |
| 338 | + " if (skiploop == false) then\n"\ |
| 339 | + " if (num_opts == '0') then\n"\ |
| 340 | + " ret = redis.call(orig_cmd, key, value, field)\n"\ |
| 341 | + " elseif (num_opts == '1') then\n"\ |
| 342 | + " ret = redis.call(orig_cmd, key, ARGV[5], value, field)\n"\ |
| 343 | + " elseif (num_opts == '2') then\n"\ |
| 344 | + " ret = redis.call(orig_cmd, key, ARGV[5], ARGV[6], value, field)\n"\ |
| 345 | + " elseif (num_opts == '3') then\n"\ |
| 346 | + " ret = redis.call(orig_cmd, key, ARGV[5], ARGV[6], ARGV[7], value, field)\n"\ |
| 347 | + " else\n"\ |
| 348 | + " ret = false\n"\ |
| 349 | + " end\n"\ |
| 350 | + " if (type(ret) ~= 'boolean') then\n"\ |
| 351 | + " redis.call('ZADD', add_set, cur_ts, field)\n"\ |
| 352 | + " end\n"\ |
| 353 | + " end\n"\ |
| 354 | + "end\n"\ |
| 355 | + "return ret\n\r\n" |
| 356 | + |
293 | 357 | #define SADD_SCRIPT "$4\r\nEVAL\r\n$1526\r\n"\ |
294 | 358 | "local key = KEYS[1]\n"\ |
295 | 359 | "local top_level_add_set = KEYS[2]\n"\ |
|
0 commit comments