| 224 | } |
| 225 | |
| 226 | static int reftable_stack_reload_once(struct reftable_stack *st, |
| 227 | const char **names, |
| 228 | int reuse_open) |
| 229 | { |
| 230 | size_t cur_len = !st->merged ? 0 : st->merged->tables_len; |
| 231 | struct reftable_table **cur = NULL; |
| 232 | struct reftable_table **reused = NULL; |
| 233 | struct reftable_table **new_tables = NULL; |
| 234 | size_t reused_len = 0, reused_alloc = 0, names_len; |
| 235 | size_t new_tables_len = 0; |
| 236 | struct reftable_merged_table *new_merged = NULL; |
| 237 | struct reftable_buf table_path = REFTABLE_BUF_INIT; |
| 238 | int err = 0; |
| 239 | size_t i; |
| 240 | |
| 241 | if (cur_len) { |
| 242 | cur = stack_copy_tables(st, cur_len); |
| 243 | if (!cur) { |
| 244 | err = REFTABLE_OUT_OF_MEMORY_ERROR; |
| 245 | goto done; |
| 246 | } |
| 247 | } |
| 248 | |
| 249 | names_len = names_length(names); |
| 250 | |
| 251 | if (names_len) { |
| 252 | new_tables = reftable_calloc(names_len, sizeof(*new_tables)); |
| 253 | if (!new_tables) { |
| 254 | err = REFTABLE_OUT_OF_MEMORY_ERROR; |
| 255 | goto done; |
| 256 | } |
| 257 | } |
| 258 | |
| 259 | while (*names) { |
| 260 | struct reftable_table *table = NULL; |
| 261 | const char *name = *names++; |
| 262 | |
| 263 | /* this is linear; we assume compaction keeps the number of |
| 264 | tables under control so this is not quadratic. */ |
| 265 | for (i = 0; reuse_open && i < cur_len; i++) { |
| 266 | if (cur[i] && 0 == strcmp(cur[i]->name, name)) { |
| 267 | table = cur[i]; |
| 268 | cur[i] = NULL; |
| 269 | |
| 270 | /* |
| 271 | * When reloading the stack fails, we end up |
| 272 | * releasing all new tables. This also |
| 273 | * includes the reused tables, even though |
| 274 | * they are still in used by the old stack. We |
| 275 | * thus need to keep them alive here, which we |
| 276 | * do by bumping their refcount. |
| 277 | */ |
| 278 | REFTABLE_ALLOC_GROW_OR_NULL(reused, |
| 279 | reused_len + 1, |
| 280 | reused_alloc); |
| 281 | if (!reused) { |
| 282 | err = REFTABLE_OUT_OF_MEMORY_ERROR; |
| 283 | goto done; |
no test coverage detected