]> git.ipfire.org Git - people/ms/libloc.git/blame - src/as-list.c
configure: Check for madvise
[people/ms/libloc.git] / src / as-list.c
CommitLineData
84a2f0c2
MT
1/*
2 libloc - A library to determine the location of someone on the Internet
3
4 Copyright (C) 2020 IPFire Development Team <info@ipfire.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15*/
16
84a2f0c2
MT
17#include <stdlib.h>
18
c12a1385
MT
19#include <libloc/as.h>
20#include <libloc/as-list.h>
21#include <libloc/private.h>
84a2f0c2
MT
22
23struct loc_as_list {
24 struct loc_ctx* ctx;
25 int refcount;
26
1a415f8c
MT
27 struct loc_as** elements;
28 size_t elements_size;
29
84a2f0c2 30 size_t size;
84a2f0c2
MT
31};
32
f13c23b7
MT
33static int loc_as_list_grow(struct loc_as_list* list) {
34 size_t size = list->elements_size * 2;
35 if (size < 1024)
36 size = 1024;
37
1a415f8c
MT
38 DEBUG(list->ctx, "Growing AS list %p by %zu to %zu\n",
39 list, size, list->elements_size + size);
40
41 struct loc_as** elements = reallocarray(list->elements,
42 list->elements_size + size, sizeof(*list->elements));
43 if (!elements)
198e382c 44 return 1;
1a415f8c
MT
45
46 list->elements = elements;
47 list->elements_size += size;
48
49 return 0;
50}
51
84a2f0c2
MT
52LOC_EXPORT int loc_as_list_new(struct loc_ctx* ctx,
53 struct loc_as_list** list) {
54 struct loc_as_list* l = calloc(1, sizeof(*l));
55 if (!l)
198e382c 56 return 1;
84a2f0c2
MT
57
58 l->ctx = loc_ref(ctx);
59 l->refcount = 1;
60
84a2f0c2
MT
61 DEBUG(l->ctx, "AS list allocated at %p\n", l);
62 *list = l;
63
64 return 0;
65}
66
67LOC_EXPORT struct loc_as_list* loc_as_list_ref(struct loc_as_list* list) {
68 list->refcount++;
69
70 return list;
71}
72
73static void loc_as_list_free(struct loc_as_list* list) {
74 DEBUG(list->ctx, "Releasing AS list at %p\n", list);
75
76 loc_as_list_clear(list);
77
78 loc_unref(list->ctx);
79 free(list);
80}
81
82LOC_EXPORT struct loc_as_list* loc_as_list_unref(struct loc_as_list* list) {
83 if (!list)
84 return NULL;
85
86 if (--list->refcount > 0)
87 return list;
88
89 loc_as_list_free(list);
90 return NULL;
91}
92
93LOC_EXPORT size_t loc_as_list_size(struct loc_as_list* list) {
94 return list->size;
95}
96
97LOC_EXPORT int loc_as_list_empty(struct loc_as_list* list) {
98 return list->size == 0;
99}
100
101LOC_EXPORT void loc_as_list_clear(struct loc_as_list* list) {
248f5e04
MT
102 if (!list->elements)
103 return;
104
84a2f0c2 105 for (unsigned int i = 0; i < list->size; i++)
1a415f8c 106 loc_as_unref(list->elements[i]);
248f5e04
MT
107
108 free(list->elements);
a6dc9324 109 list->elements = NULL;
248f5e04
MT
110 list->elements_size = 0;
111
112 list->size = 0;
84a2f0c2
MT
113}
114
115LOC_EXPORT struct loc_as* loc_as_list_get(struct loc_as_list* list, size_t index) {
116 // Check index
117 if (index >= list->size)
118 return NULL;
119
1a415f8c 120 return loc_as_ref(list->elements[index]);
84a2f0c2
MT
121}
122
123LOC_EXPORT int loc_as_list_append(
124 struct loc_as_list* list, struct loc_as* as) {
125 if (loc_as_list_contains(list, as))
126 return 0;
127
128 // Check if we have space left
1a415f8c 129 if (list->size >= list->elements_size) {
f13c23b7 130 int r = loc_as_list_grow(list);
1a415f8c
MT
131 if (r)
132 return r;
84a2f0c2
MT
133 }
134
135 DEBUG(list->ctx, "%p: Appending AS %p to list\n", list, as);
136
1a415f8c 137 list->elements[list->size++] = loc_as_ref(as);
84a2f0c2
MT
138
139 return 0;
140}
141
142LOC_EXPORT int loc_as_list_contains(
143 struct loc_as_list* list, struct loc_as* as) {
144 for (unsigned int i = 0; i < list->size; i++) {
1a415f8c 145 if (loc_as_cmp(as, list->elements[i]) == 0)
84a2f0c2
MT
146 return 1;
147 }
148
149 return 0;
150}
151
152LOC_EXPORT int loc_as_list_contains_number(
153 struct loc_as_list* list, uint32_t number) {
154 struct loc_as* as;
155
156 int r = loc_as_new(list->ctx, &as, number);
157 if (r)
158 return -1;
159
160 r = loc_as_list_contains(list, as);
161 loc_as_unref(as);
162
163 return r;
164}
233311e8
MT
165
166static int __loc_as_cmp(const void* as1, const void* as2) {
167 return loc_as_cmp(*(struct loc_as**)as1, *(struct loc_as**)as2);
168}
169
170LOC_EXPORT void loc_as_list_sort(struct loc_as_list* list) {
171 // Sort everything
172 qsort(list->elements, list->size, sizeof(*list->elements), __loc_as_cmp);
173}