| 1551 | } |
| 1552 | |
| 1553 | static void add_delta_base_cache(struct packed_git *p, off_t base_offset, |
| 1554 | void *base, size_t base_size, |
| 1555 | size_t delta_base_cache_limit, |
| 1556 | enum object_type type) |
| 1557 | { |
| 1558 | struct delta_base_cache_entry *ent; |
| 1559 | struct list_head *lru, *tmp; |
| 1560 | |
| 1561 | /* |
| 1562 | * Check required to avoid redundant entries when more than one thread |
| 1563 | * is unpacking the same object, in unpack_entry() (since its phases I |
| 1564 | * and III might run concurrently across multiple threads). |
| 1565 | */ |
| 1566 | if (in_delta_base_cache(p, base_offset)) { |
| 1567 | free(base); |
| 1568 | return; |
| 1569 | } |
| 1570 | |
| 1571 | delta_base_cached += base_size; |
| 1572 | |
| 1573 | list_for_each_safe(lru, tmp, &delta_base_cache_lru) { |
| 1574 | struct delta_base_cache_entry *f = |
| 1575 | list_entry(lru, struct delta_base_cache_entry, lru); |
| 1576 | if (delta_base_cached <= delta_base_cache_limit) |
| 1577 | break; |
| 1578 | release_delta_base_cache(f); |
| 1579 | } |
| 1580 | |
| 1581 | ent = xmalloc(sizeof(*ent)); |
| 1582 | ent->key.p = p; |
| 1583 | ent->key.base_offset = base_offset; |
| 1584 | ent->type = type; |
| 1585 | ent->data = base; |
| 1586 | ent->size = base_size; |
| 1587 | list_add_tail(&ent->lru, &delta_base_cache_lru); |
| 1588 | |
| 1589 | if (!delta_base_cache.cmpfn) |
| 1590 | hashmap_init(&delta_base_cache, delta_base_cache_hash_cmp, NULL, 0); |
| 1591 | hashmap_entry_init(&ent->ent, pack_entry_hash(p, base_offset)); |
| 1592 | hashmap_add(&delta_base_cache, &ent->ent); |
| 1593 | } |
| 1594 | |
| 1595 | static int packed_object_info_with_index_pos(struct packed_git *p, off_t obj_offset, |
| 1596 | uint32_t *maybe_index_pos, struct object_info *oi) |
no test coverage detected