X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fnetwork-list.c;h=698d3abce98bd3380205e1987881fcef91d0e6df;hb=HEAD;hp=c70c9986928d60a2bee050fd5ee2275e74468b9e;hpb=8332f92a0bf96782ccbed871f45a45dadbb67dc7;p=people%2Fms%2Flibloc.git diff --git a/src/network-list.c b/src/network-list.c index c70c998..bca4422 100644 --- a/src/network-list.c +++ b/src/network-list.c @@ -33,14 +33,18 @@ struct loc_network_list { size_t size; }; -static int loc_network_list_grow(struct loc_network_list* list, size_t size) { +static int loc_network_list_grow(struct loc_network_list* list) { + size_t size = list->elements_size * 2; + if (size < 1024) + size = 1024; + DEBUG(list->ctx, "Growing network list %p by %zu to %zu\n", list, size, list->elements_size + size); struct loc_network** elements = reallocarray(list->elements, list->elements_size + size, sizeof(*list->elements)); if (!elements) - return -errno; + return 1; list->elements = elements; list->elements_size += size; @@ -79,9 +83,6 @@ static void loc_network_list_free(struct loc_network_list* list) { } LOC_EXPORT struct loc_network_list* loc_network_list_unref(struct loc_network_list* list) { - if (!list) - return NULL; - if (--list->refcount > 0) return list; @@ -221,7 +222,7 @@ LOC_EXPORT int loc_network_list_push(struct loc_network_list* list, struct loc_n // Check if we have space left if (list->size >= list->elements_size) { - int r = loc_network_list_grow(list, 64); + int r = loc_network_list_grow(list); if (r) return r; } @@ -275,6 +276,29 @@ LOC_EXPORT struct loc_network* loc_network_list_pop_first(struct loc_network_lis return network; } +int loc_network_list_remove(struct loc_network_list* list, struct loc_network* network) { + int found = 0; + + // Find the network on the list + off_t index = loc_network_list_find(list, network, &found); + + // Nothing to do if the network wasn't found + if (!found) + return 0; + + // Dereference the network at the position + loc_network_unref(list->elements[index]); + + // Move all other elements back + for (unsigned int i = index; i < list->size - 1; i++) + list->elements[i] = list->elements[i+1]; + + // The list is shorter now + --list->size; + + return 0; +} + LOC_EXPORT int loc_network_list_contains(struct loc_network_list* list, struct loc_network* network) { int found = 0; @@ -382,3 +406,34 @@ int loc_network_list_summarize(struct loc_ctx* ctx, return 0; } + +void loc_network_list_remove_with_prefix_smaller_than( + struct loc_network_list* list, const unsigned int prefix) { + unsigned int p = 0; + + // Count how many networks were removed + unsigned int removed = 0; + + for (unsigned int i = 0; i < list->size; i++) { + // Fetch the prefix + p = loc_network_prefix(list->elements[i]); + + if (p > prefix) { + // Drop this network + loc_network_unref(list->elements[i]); + + // Increment counter + removed++; + + continue; + } + + // Move pointers backwards to keep the list filled + list->elements[i - removed] = list->elements[i]; + } + + // Adjust size + list->size -= removed; + + return; +}