summaryrefslogtreecommitdiff
path: root/packfile-list.c
blob: d6d411823c34a911bd7768721ea185840769e153 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include "git-compat-util.h"
#include "packfile.h"
#include "packfile-list.h"

void packfile_list_clear(struct packfile_list *list)
{
	struct packfile_list_entry *e, *next;

	for (e = list->head; e; e = next) {
		next = e->next;
		free(e);
	}

	list->head = list->tail = NULL;
}

static struct packfile_list_entry *packfile_list_remove_internal(struct packfile_list *list,
								 struct packed_git *pack)
{
	struct packfile_list_entry *e, *prev;

	for (e = list->head, prev = NULL; e; prev = e, e = e->next) {
		if (e->pack != pack)
			continue;

		if (prev)
			prev->next = e->next;
		if (list->head == e)
			list->head = e->next;
		if (list->tail == e)
			list->tail = prev;

		return e;
	}

	return NULL;
}

void packfile_list_remove(struct packfile_list *list, struct packed_git *pack)
{
	free(packfile_list_remove_internal(list, pack));
}

void packfile_list_prepend(struct packfile_list *list, struct packed_git *pack)
{
	struct packfile_list_entry *entry;

	entry = packfile_list_remove_internal(list, pack);
	if (!entry) {
		entry = xmalloc(sizeof(*entry));
		entry->pack = pack;
	}
	entry->next = list->head;

	list->head = entry;
	if (!list->tail)
		list->tail = entry;
}

void packfile_list_append(struct packfile_list *list, struct packed_git *pack,
			  int skip_dup_check)
{
	struct packfile_list_entry *entry;

	entry = skip_dup_check ? NULL : packfile_list_remove_internal(list, pack);
	if (!entry) {
		entry = xmalloc(sizeof(*entry));
		entry->pack = pack;
	}
	entry->next = NULL;

	if (list->tail) {
		list->tail->next = entry;
		list->tail = entry;
	} else {
		list->head = list->tail = entry;
	}
}

struct packed_git *packfile_list_find_oid(struct packfile_list_entry *packs,
					  const struct object_id *oid)
{
	for (; packs; packs = packs->next)
		if (find_pack_entry_one(oid, packs->pack))
			return packs->pack;
	return NULL;
}