* To insert a leaf_node: * Search to the tree location appropriate for the given leaf_node's key: * - If location is unused (NULL), store the tweaked pointer directly there * - If location holds a note entry that matches the note-to-be-inserted, then * combine the two notes (by calling the given combine_notes function). * - If location holds a note entry that matches the subtree-to-be-inser
| 251 | * node-to-be-inserted, and store the new int_node into the location. |
| 252 | */ |
| 253 | static int note_tree_insert(struct notes_tree *t, struct int_node *tree, |
| 254 | unsigned char n, struct leaf_node *entry, unsigned char type, |
| 255 | combine_notes_fn combine_notes) |
| 256 | { |
| 257 | struct int_node *new_node; |
| 258 | struct leaf_node *l; |
| 259 | void **p = note_tree_search(t, &tree, &n, entry->key_oid.hash); |
| 260 | int ret = 0; |
| 261 | |
| 262 | assert(GET_PTR_TYPE(entry) == 0); /* no type bits set */ |
| 263 | l = (struct leaf_node *) CLR_PTR_TYPE(*p); |
| 264 | switch (GET_PTR_TYPE(*p)) { |
| 265 | case PTR_TYPE_NULL: |
| 266 | assert(!*p); |
| 267 | if (is_null_oid(&entry->val_oid)) |
| 268 | free(entry); |
| 269 | else |
| 270 | *p = SET_PTR_TYPE(entry, type); |
| 271 | return 0; |
| 272 | case PTR_TYPE_NOTE: |
| 273 | switch (type) { |
| 274 | case PTR_TYPE_NOTE: |
| 275 | if (oideq(&l->key_oid, &entry->key_oid)) { |
| 276 | /* skip concatenation if l == entry */ |
| 277 | if (oideq(&l->val_oid, &entry->val_oid)) { |
| 278 | free(entry); |
| 279 | return 0; |
| 280 | } |
| 281 | |
| 282 | ret = combine_notes(&l->val_oid, |
| 283 | &entry->val_oid); |
| 284 | if (!ret && is_null_oid(&l->val_oid)) |
| 285 | note_tree_remove(t, tree, n, entry); |
| 286 | free(entry); |
| 287 | return ret; |
| 288 | } |
| 289 | break; |
| 290 | case PTR_TYPE_SUBTREE: |
| 291 | if (!SUBTREE_SHA1_PREFIXCMP(l->key_oid.hash, |
| 292 | entry->key_oid.hash)) { |
| 293 | /* unpack 'entry' */ |
| 294 | load_subtree(t, entry, tree, n); |
| 295 | free(entry); |
| 296 | return 0; |
| 297 | } |
| 298 | break; |
| 299 | } |
| 300 | break; |
| 301 | case PTR_TYPE_SUBTREE: |
| 302 | if (!SUBTREE_SHA1_PREFIXCMP(entry->key_oid.hash, l->key_oid.hash)) { |
| 303 | /* unpack 'l' and restart insert */ |
| 304 | *p = NULL; |
| 305 | load_subtree(t, l, tree, n); |
| 306 | free(l); |
| 307 | return note_tree_insert(t, tree, n, entry, type, |
| 308 | combine_notes); |
| 309 | } |
| 310 | break; |
no test coverage detected