Get an edge streamID of a given listpack. * 'master_id' is an input param, used to build the 'edge_id' output param */
| 297 | /* Get an edge streamID of a given listpack. |
| 298 | * 'master_id' is an input param, used to build the 'edge_id' output param */ |
| 299 | int lpGetEdgeStreamID(unsigned char *lp, int first, streamID *master_id, streamID *edge_id) |
| 300 | { |
| 301 | if (lp == NULL) |
| 302 | return 0; |
| 303 | |
| 304 | unsigned char *lp_ele; |
| 305 | |
| 306 | /* We need to seek either the first or the last entry depending |
| 307 | * on the direction of the iteration. */ |
| 308 | if (first) { |
| 309 | /* Get the master fields count. */ |
| 310 | lp_ele = lpFirst(lp); /* Seek items count */ |
| 311 | lp_ele = lpNext(lp, lp_ele); /* Seek deleted count. */ |
| 312 | lp_ele = lpNext(lp, lp_ele); /* Seek num fields. */ |
| 313 | int64_t master_fields_count = lpGetInteger(lp_ele); |
| 314 | lp_ele = lpNext(lp, lp_ele); /* Seek first field. */ |
| 315 | |
| 316 | /* If we are iterating in normal order, skip the master fields |
| 317 | * to seek the first actual entry. */ |
| 318 | for (int64_t i = 0; i < master_fields_count; i++) |
| 319 | lp_ele = lpNext(lp, lp_ele); |
| 320 | |
| 321 | /* If we are going forward, skip the previous entry's |
| 322 | * lp-count field (or in case of the master entry, the zero |
| 323 | * term field) */ |
| 324 | lp_ele = lpNext(lp, lp_ele); |
| 325 | if (lp_ele == NULL) |
| 326 | return 0; |
| 327 | } else { |
| 328 | /* If we are iterating in reverse direction, just seek the |
| 329 | * last part of the last entry in the listpack (that is, the |
| 330 | * fields count). */ |
| 331 | lp_ele = lpLast(lp); |
| 332 | |
| 333 | /* If we are going backward, read the number of elements this |
| 334 | * entry is composed of, and jump backward N times to seek |
| 335 | * its start. */ |
| 336 | int64_t lp_count = lpGetInteger(lp_ele); |
| 337 | if (lp_count == 0) /* We reached the master entry. */ |
| 338 | return 0; |
| 339 | |
| 340 | while (lp_count--) |
| 341 | lp_ele = lpPrev(lp, lp_ele); |
| 342 | } |
| 343 | |
| 344 | lp_ele = lpNext(lp, lp_ele); /* Seek ID (lp_ele currently points to 'flags'). */ |
| 345 | |
| 346 | /* Get the ID: it is encoded as difference between the master |
| 347 | * ID and this entry ID. */ |
| 348 | streamID id = *master_id; |
| 349 | id.ms += lpGetInteger(lp_ele); |
| 350 | lp_ele = lpNext(lp, lp_ele); |
| 351 | id.seq += lpGetInteger(lp_ele); |
| 352 | *edge_id = id; |
| 353 | return 1; |
| 354 | } |
| 355 | |
| 356 | /* Debugging function to log the full content of a listpack. Useful |
no test coverage detected