Coverage Report

Created: 2026-01-10 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/decorate.c
Line
Count
Source
1
/*
2
 * decorate.c - decorate a git object with some arbitrary
3
 * data.
4
 */
5
6
#include "git-compat-util.h"
7
#include "object.h"
8
#include "decorate.h"
9
10
static unsigned int hash_obj(const struct object *obj, unsigned int n)
11
0
{
12
0
  return oidhash(&obj->oid) % n;
13
0
}
14
15
static void *insert_decoration(struct decoration *n, const struct object *base, void *decoration)
16
0
{
17
0
  struct decoration_entry *entries = n->entries;
18
0
  unsigned int j = hash_obj(base, n->size);
19
20
0
  while (entries[j].base) {
21
0
    if (entries[j].base == base) {
22
0
      void *old = entries[j].decoration;
23
0
      entries[j].decoration = decoration;
24
0
      return old;
25
0
    }
26
0
    if (++j >= n->size)
27
0
      j = 0;
28
0
  }
29
0
  entries[j].base = base;
30
0
  entries[j].decoration = decoration;
31
0
  n->nr++;
32
0
  return NULL;
33
0
}
34
35
static void grow_decoration(struct decoration *n)
36
0
{
37
0
  unsigned int i;
38
0
  unsigned int old_size = n->size;
39
0
  struct decoration_entry *old_entries = n->entries;
40
41
0
  n->size = (old_size + 1000) * 3 / 2;
42
0
  CALLOC_ARRAY(n->entries, n->size);
43
0
  n->nr = 0;
44
45
0
  for (i = 0; i < old_size; i++) {
46
0
    const struct object *base = old_entries[i].base;
47
0
    void *decoration = old_entries[i].decoration;
48
49
0
    if (!decoration)
50
0
      continue;
51
0
    insert_decoration(n, base, decoration);
52
0
  }
53
0
  free(old_entries);
54
0
}
55
56
void *add_decoration(struct decoration *n, const struct object *obj,
57
    void *decoration)
58
0
{
59
0
  if ((n->nr + 1) > n->size * 2 / 3)
60
0
    grow_decoration(n);
61
0
  return insert_decoration(n, obj, decoration);
62
0
}
63
64
void *lookup_decoration(struct decoration *n, const struct object *obj)
65
0
{
66
0
  unsigned int j;
67
68
  /* nothing to lookup */
69
0
  if (!n->size)
70
0
    return NULL;
71
0
  j = hash_obj(obj, n->size);
72
0
  for (;;) {
73
0
    struct decoration_entry *ref = n->entries + j;
74
0
    if (ref->base == obj)
75
0
      return ref->decoration;
76
0
    if (!ref->base)
77
0
      return NULL;
78
0
    if (++j == n->size)
79
0
      j = 0;
80
0
  }
81
0
}
82
83
void clear_decoration(struct decoration *n, void (*free_cb)(void *))
84
0
{
85
0
  if (free_cb) {
86
0
    unsigned int i;
87
0
    for (i = 0; i < n->size; i++) {
88
0
      void *d = n->entries[i].decoration;
89
0
      if (d)
90
0
        free_cb(d);
91
0
    }
92
0
  }
93
94
  FREE_AND_NULL(n->entries);
95
0
  n->size = n->nr = 0;
96
0
}