This is a helper function for the COPY command. * Duplicate a Stream object, with the guarantee that the returned object * has the same encoding as the original one. * * The resulting object always has refcount set to 1 */
| 149 | * |
| 150 | * The resulting object always has refcount set to 1 */ |
| 151 | robj *streamDup(robj *o) { |
| 152 | robj *sobj; |
| 153 | |
| 154 | serverAssert(o->type == OBJ_STREAM); |
| 155 | |
| 156 | switch (o->encoding) { |
| 157 | case OBJ_ENCODING_STREAM: |
| 158 | sobj = createStreamObject(); |
| 159 | break; |
| 160 | default: |
| 161 | serverPanic("Wrong encoding."); |
| 162 | break; |
| 163 | } |
| 164 | |
| 165 | stream *s; |
| 166 | stream *new_s; |
| 167 | s = (stream*)ptrFromObj(o); |
| 168 | new_s = (stream*)ptrFromObj(sobj); |
| 169 | |
| 170 | raxIterator ri; |
| 171 | uint64_t rax_key[2]; |
| 172 | raxStart(&ri, s->rax); |
| 173 | raxSeek(&ri, "^", NULL, 0); |
| 174 | size_t lp_bytes = 0; /* Total bytes in the listpack. */ |
| 175 | unsigned char *lp = NULL; /* listpack pointer. */ |
| 176 | /* Get a reference to the listpack node. */ |
| 177 | while (raxNext(&ri)) { |
| 178 | lp = (unsigned char*)ri.data; |
| 179 | lp_bytes = lpBytes(lp); |
| 180 | unsigned char *new_lp = (unsigned char*)zmalloc(lp_bytes); |
| 181 | memcpy(new_lp, lp, lp_bytes); |
| 182 | memcpy(rax_key, ri.key, sizeof(rax_key)); |
| 183 | raxInsert(new_s->rax, (unsigned char *)&rax_key, sizeof(rax_key), |
| 184 | new_lp, NULL); |
| 185 | } |
| 186 | new_s->length = s->length; |
| 187 | new_s->last_id = s->last_id; |
| 188 | raxStop(&ri); |
| 189 | |
| 190 | if (s->cgroups == NULL) return sobj; |
| 191 | |
| 192 | /* Consumer Groups */ |
| 193 | raxIterator ri_cgroups; |
| 194 | raxStart(&ri_cgroups, s->cgroups); |
| 195 | raxSeek(&ri_cgroups, "^", NULL, 0); |
| 196 | while (raxNext(&ri_cgroups)) { |
| 197 | streamCG *cg = (streamCG*)ri_cgroups.data; |
| 198 | streamCG *new_cg = streamCreateCG(new_s, (char *)ri_cgroups.key, |
| 199 | ri_cgroups.key_len, &cg->last_id); |
| 200 | |
| 201 | serverAssert(new_cg != NULL); |
| 202 | |
| 203 | /* Consumer Group PEL */ |
| 204 | raxIterator ri_cg_pel; |
| 205 | raxStart(&ri_cg_pel,cg->pel); |
| 206 | raxSeek(&ri_cg_pel,"^",NULL,0); |
| 207 | while(raxNext(&ri_cg_pel)){ |
| 208 | streamNACK *nack = (streamNACK*)ri_cg_pel.data; |
no test coverage detected