forked from osm2pgsql-dev/osm2pgsql
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbinarysearcharray.c
117 lines (110 loc) · 2.81 KB
/
binarysearcharray.c
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "osmtypes.h"
#include "binarysearcharray.h"
static int binary_search_lookup(struct binary_search_array * array, int key)
{
int a = 0;
int b = array->size - 1;
while (a <= b)
{
int pivot = ((b - a) >> 1) + a;
if (array->array[pivot].key == key)
{
return pivot;
}
else if (array->array[pivot].key > key)
{
b = pivot - 1;
}
else
{
a = pivot + 1;
}
}
if ((a < array->size) && (array->array[a].key < key))
a++;
return a | (1 << (sizeof(int) * 8 - 1));
}
osmid_t binary_search_get(struct binary_search_array * array, int key)
{
int idx;
if (array->size == 0)
return -1;
idx = binary_search_lookup(array, key);
if (idx < 0)
{
return -1;
}
else
{
return array->array[idx].value;
}
}
void binary_search_remove(struct binary_search_array * array, int key)
{
int idx = binary_search_lookup(array, key);
if (idx < 0)
{
return;
}
else
{
memmove(&(array->array[idx]), &(array->array[idx + 1]),
sizeof(struct key_val_tuple) * (array->capacity - idx - 1));
array->size--;
}
}
void binary_search_add(struct binary_search_array * array, int key,
osmid_t value)
{
int idx;
if (array->size < array->capacity)
{
if (array->size == 0)
{
array->array[0].key = key;
array->array[0].value = value;
array->size++;
return;
}
idx = binary_search_lookup(array, key);
if (idx < 0)
{
idx = idx & (~(1 << (sizeof(int) * 8 - 1)));
memmove(&(array->array[idx + 1]), &(array->array[idx]),
sizeof(struct key_val_tuple) * (array->capacity - idx - 1));
array->array[idx].key = key;
array->array[idx].value = value;
array->size++;
}
else
{
fprintf(stderr, "dupplicate!\n");
exit(1);
}
}
}
struct binary_search_array * init_search_array(int capacity)
{
struct binary_search_array * array = calloc(1,
sizeof(struct binary_search_array));
array->array = calloc(capacity + 1, sizeof(struct key_val_tuple));
if (!array->array) {
fprintf(stderr, "Out of memory trying to allocate %li bytes for binary search array\n", ((capacity + 1) * sizeof(struct key_val_tuple)));
exit_nicely();
}
array->capacity = capacity;
array->size = 0;
return array;
}
void shutdown_search_array(struct binary_search_array ** array)
{
free((*array)->array);
(*array)->array = NULL;
(*array)->capacity = 0;
free(*array);
*array = NULL;
}