geoip2_c 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +3 -4
- data/README.md +21 -3
- data/docker-compose.yml +15 -1
- data/dockerfiles/{Dockerfile-ruby2.1 → Dockerfile-ruby2.5} +1 -1
- data/dockerfiles/{Dockerfile-ruby2.2 → Dockerfile-ruby2.6} +1 -1
- data/ext/geoip2/geoip2.c +5 -3
- data/ext/geoip2/libmaxminddb/.gitignore +3 -0
- data/ext/geoip2/libmaxminddb/.travis.yml +24 -2
- data/ext/geoip2/libmaxminddb/Changes.md +39 -0
- data/ext/geoip2/libmaxminddb/README.dev.md +41 -30
- data/ext/geoip2/libmaxminddb/README.md +3 -3
- data/ext/geoip2/libmaxminddb/bin/Makefile.am +5 -0
- data/ext/geoip2/libmaxminddb/bin/mmdblookup.c +333 -15
- data/ext/geoip2/libmaxminddb/configure.ac +5 -5
- data/ext/geoip2/libmaxminddb/dev-bin/ppa-release.sh +8 -5
- data/ext/geoip2/libmaxminddb/dev-bin/release.sh +7 -0
- data/ext/geoip2/libmaxminddb/dev-bin/valgrind-all.pl +10 -3
- data/ext/geoip2/libmaxminddb/include/maxminddb.h +11 -2
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.vcxproj +3 -1
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.vcxproj.filters +7 -1
- data/ext/geoip2/libmaxminddb/src/Makefile.am +18 -2
- data/ext/geoip2/libmaxminddb/src/data-pool.c +180 -0
- data/ext/geoip2/libmaxminddb/src/data-pool.h +52 -0
- data/ext/geoip2/libmaxminddb/src/maxminddb.c +58 -48
- data/ext/geoip2/libmaxminddb/t/Makefile.am +6 -2
- data/ext/geoip2/libmaxminddb/t/bad_databases_t.c +1 -0
- data/ext/geoip2/libmaxminddb/t/basic_lookup_t.c +35 -0
- data/ext/geoip2/libmaxminddb/t/data-pool-t.c +374 -0
- data/ext/geoip2/libmaxminddb/t/external_symbols_t.pl +106 -0
- data/lib/geoip2/version.rb +1 -1
- metadata +9 -7
- data/dockerfiles/Dockerfile-ruby2.3 +0 -8
@@ -2,7 +2,7 @@
|
|
2
2
|
# Process this file with autoconf to produce a configure script.
|
3
3
|
|
4
4
|
AC_PREREQ([2.63])
|
5
|
-
AC_INIT([libmaxminddb], [1.2
|
5
|
+
AC_INIT([libmaxminddb], [1.3.2], [support@maxmind.com])
|
6
6
|
AC_CONFIG_SRCDIR([include/maxminddb.h])
|
7
7
|
AC_CONFIG_HEADERS([config.h include/maxminddb_config.h])
|
8
8
|
|
@@ -63,9 +63,11 @@ AC_CHECK_HEADERS([arpa/inet.h assert.h fcntl.h inttypes.h libgen.h math.h netdb.
|
|
63
63
|
# so we only run them on non MinGW-Systems. For MinGW we also need to link
|
64
64
|
# against ws2_32.
|
65
65
|
AC_CANONICAL_HOST
|
66
|
+
is_windows=false
|
66
67
|
case $host_os in
|
67
68
|
mingw*)
|
68
69
|
LDFLAGS="-lws2_32"
|
70
|
+
is_windows=true
|
69
71
|
;;
|
70
72
|
*)
|
71
73
|
AC_TYPE_OFF_T
|
@@ -77,6 +79,7 @@ case $host_os in
|
|
77
79
|
;;
|
78
80
|
esac
|
79
81
|
|
82
|
+
AM_CONDITIONAL([WINDOWS], [test x$is_windows = xtrue])
|
80
83
|
|
81
84
|
# This check is backwards in order to make life easier for people writing
|
82
85
|
# extensions in other languages that link to this library. If they want to
|
@@ -94,15 +97,12 @@ AC_CHECK_TYPE(
|
|
94
97
|
|
95
98
|
AC_CHECK_TYPES([boolean])
|
96
99
|
|
97
|
-
|
98
|
-
[open_memstream],
|
99
|
-
[AC_DEFINE([HAVE_OPEN_MEMSTREAM], [1], [Has an open_memstream() function])])
|
100
|
+
AC_CHECK_FUNCS([clock_gettime open_memstream])
|
100
101
|
|
101
102
|
AC_C_BIGENDIAN(
|
102
103
|
[AC_DEFINE([MMDB_LITTLE_ENDIAN], [0], [System is big-endian])],
|
103
104
|
[AC_DEFINE([MMDB_LITTLE_ENDIAN], [1], [System is little-endian])])
|
104
105
|
|
105
|
-
AC_FUNC_MALLOC
|
106
106
|
AC_FUNC_MMAP
|
107
107
|
|
108
108
|
AC_SEARCH_LIBS([fabs], [m])
|
@@ -4,7 +4,7 @@ set -e
|
|
4
4
|
set -x
|
5
5
|
set -u
|
6
6
|
|
7
|
-
DISTS=(
|
7
|
+
DISTS=( artful zesty xenial trusty precise )
|
8
8
|
|
9
9
|
VERSION=$(perl -MFile::Slurp::Tiny=read_file -MDateTime <<EOF
|
10
10
|
use v5.16;
|
@@ -27,11 +27,11 @@ pushd "$SRCDIR"
|
|
27
27
|
git merge "$VERSION"
|
28
28
|
|
29
29
|
for dist in "${DISTS[@]}"; do
|
30
|
-
git clean -xfd
|
31
|
-
git reset HEAD --hard
|
32
|
-
|
33
30
|
dch -v "$VERSION-0+maxmind1~$dist" -D "$dist" -u low "New upstream release."
|
34
31
|
gbp buildpackage -S --git-ignore-new
|
32
|
+
|
33
|
+
git clean -xfd
|
34
|
+
git reset HEAD --hard
|
35
35
|
done
|
36
36
|
|
37
37
|
read -e -p "Release to PPA? (y/n)" SHOULD_RELEASE
|
@@ -41,9 +41,12 @@ if [ "$SHOULD_RELEASE" != "y" ]; then
|
|
41
41
|
exit 1
|
42
42
|
fi
|
43
43
|
|
44
|
+
# Upload to launchpad
|
44
45
|
dput ppa:maxmind/ppa ../*source.changes
|
45
46
|
|
46
|
-
|
47
|
+
# Make the changelog up to date in git
|
48
|
+
|
49
|
+
dch -v "$VERSION-0+maxmind1" -D "${DISTS[0]}" -u low "New upstream release."
|
47
50
|
|
48
51
|
git add debian/changelog
|
49
52
|
git commit -m "Update debian/changelog for $VERSION"
|
@@ -47,6 +47,13 @@ if [ -n "$(git status --porcelain)" ]; then
|
|
47
47
|
git commit -m "Bumped version to $version"
|
48
48
|
fi
|
49
49
|
|
50
|
+
./bootstrap
|
51
|
+
./configure
|
52
|
+
make
|
53
|
+
make check
|
54
|
+
make clean
|
55
|
+
make safedist
|
56
|
+
|
50
57
|
if [ ! -d .gh-pages ]; then
|
51
58
|
echo "Checking out gh-pages in .gh-pages"
|
52
59
|
git clone -b gh-pages git@github.com:maxmind/libmaxminddb.git .gh-pages
|
@@ -1,5 +1,10 @@
|
|
1
1
|
#!/usr/bin/env perl
|
2
2
|
|
3
|
+
# Note to run this you will probably want to build with ./configure
|
4
|
+
# --disable-shared. You don't want to valgrind the libtool script.
|
5
|
+
#
|
6
|
+
# Also make sure you compile the tests first (`make check').
|
7
|
+
|
3
8
|
use strict;
|
4
9
|
use warnings;
|
5
10
|
|
@@ -11,11 +16,13 @@ my $top_dir = "$Bin/..";
|
|
11
16
|
|
12
17
|
my $output;
|
13
18
|
|
14
|
-
my @tests
|
19
|
+
my @tests;
|
20
|
+
push @tests, glob "$top_dir/t/*_t";
|
21
|
+
push @tests, glob "$top_dir/t/*-t";
|
15
22
|
|
16
23
|
my @mmdblookup = (
|
17
24
|
"$top_dir/bin/mmdblookup",
|
18
|
-
'--file', "$top_dir/maxmind-db/test-data/MaxMind-DB-test-decoder.mmdb",
|
25
|
+
'--file', "$top_dir/t/maxmind-db/test-data/MaxMind-DB-test-decoder.mmdb",
|
19
26
|
'--ip',
|
20
27
|
);
|
21
28
|
|
@@ -31,7 +38,7 @@ my @cmds = (
|
|
31
38
|
for my $cmd (@cmds) {
|
32
39
|
my $output;
|
33
40
|
run3(
|
34
|
-
[ qw( valgrind --leak-check=full -- ), @{$cmd} ],
|
41
|
+
[ qw( valgrind -v --leak-check=full --show-leak-kinds=all -- ), @{$cmd} ],
|
35
42
|
\undef,
|
36
43
|
\$output,
|
37
44
|
\$output,
|
@@ -5,8 +5,16 @@ extern "C" {
|
|
5
5
|
#ifndef MAXMINDDB_H
|
6
6
|
#define MAXMINDDB_H
|
7
7
|
|
8
|
+
/* Request POSIX.1-2008. However, we want to remain compatible with
|
9
|
+
* POSIX.1-2001 (since we have been historically and see no reason to drop
|
10
|
+
* compatibility). By requesting POSIX.1-2008, we can conditionally use
|
11
|
+
* features provided by that standard if the implementation provides it. We can
|
12
|
+
* check for what the implementation provides by checking the _POSIX_VERSION
|
13
|
+
* macro after including unistd.h. If a feature is in POSIX.1-2008 but not
|
14
|
+
* POSIX.1-2001, check that macro before using the feature (or check for the
|
15
|
+
* feature directly if possible). */
|
8
16
|
#ifndef _POSIX_C_SOURCE
|
9
|
-
#define _POSIX_C_SOURCE
|
17
|
+
#define _POSIX_C_SOURCE 200809L
|
10
18
|
#endif
|
11
19
|
|
12
20
|
#include "maxminddb_config.h"
|
@@ -20,7 +28,7 @@ extern "C" {
|
|
20
28
|
#include <winsock2.h>
|
21
29
|
#include <ws2tcpip.h>
|
22
30
|
/* libmaxminddb package version from configure */
|
23
|
-
#define PACKAGE_VERSION "1.2
|
31
|
+
#define PACKAGE_VERSION "1.3.2"
|
24
32
|
|
25
33
|
typedef ADDRESS_FAMILY sa_family_t;
|
26
34
|
|
@@ -135,6 +143,7 @@ typedef struct MMDB_entry_data_s {
|
|
135
143
|
typedef struct MMDB_entry_data_list_s {
|
136
144
|
MMDB_entry_data_s entry_data;
|
137
145
|
struct MMDB_entry_data_list_s *next;
|
146
|
+
void *pool;
|
138
147
|
} MMDB_entry_data_list_s;
|
139
148
|
|
140
149
|
typedef struct MMDB_description_s {
|
@@ -20,9 +20,11 @@
|
|
20
20
|
</ItemGroup>
|
21
21
|
<ItemGroup>
|
22
22
|
<ClCompile Include="..\..\src\maxminddb.c" />
|
23
|
+
<ClCompile Include="..\..\src\data-pool.c" />
|
23
24
|
</ItemGroup>
|
24
25
|
<ItemGroup>
|
25
26
|
<ClInclude Include="..\..\include\maxminddb.h" />
|
27
|
+
<ClInclude Include="..\..\src\data-pool.h" />
|
26
28
|
</ItemGroup>
|
27
29
|
<ItemGroup>
|
28
30
|
<None Include="README" />
|
@@ -138,4 +140,4 @@
|
|
138
140
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
139
141
|
<ImportGroup Label="ExtensionTargets">
|
140
142
|
</ImportGroup>
|
141
|
-
</Project>
|
143
|
+
</Project>
|
@@ -14,13 +14,19 @@
|
|
14
14
|
<ClCompile Include="..\..\src\maxminddb.c">
|
15
15
|
<Filter>Source Files</Filter>
|
16
16
|
</ClCompile>
|
17
|
+
<ClCompile Include="..\..\src\data-pool.c">
|
18
|
+
<Filter>Source Files</Filter>
|
19
|
+
</ClCompile>
|
17
20
|
</ItemGroup>
|
18
21
|
<ItemGroup>
|
19
22
|
<ClInclude Include="..\..\include\maxminddb.h">
|
20
23
|
<Filter>Header Files</Filter>
|
21
24
|
</ClInclude>
|
25
|
+
<ClInclude Include="..\..\src\data-pool.h">
|
26
|
+
<Filter>Header Files</Filter>
|
27
|
+
</ClInclude>
|
22
28
|
</ItemGroup>
|
23
29
|
<ItemGroup>
|
24
30
|
<None Include="README" />
|
25
31
|
</ItemGroup>
|
26
|
-
</Project>
|
32
|
+
</Project>
|
@@ -2,8 +2,24 @@ include $(top_srcdir)/common.mk
|
|
2
2
|
|
3
3
|
lib_LTLIBRARIES = libmaxminddb.la
|
4
4
|
|
5
|
-
libmaxminddb_la_SOURCES = maxminddb.c maxminddb-compat-util.h
|
6
|
-
|
5
|
+
libmaxminddb_la_SOURCES = maxminddb.c maxminddb-compat-util.h \
|
6
|
+
data-pool.c data-pool.h
|
7
|
+
libmaxminddb_la_LDFLAGS = -version-info 0:7:0 -export-symbols-regex '^MMDB_.*'
|
7
8
|
include_HEADERS = $(top_srcdir)/include/maxminddb.h
|
8
9
|
|
9
10
|
pkgconfig_DATA = libmaxminddb.pc
|
11
|
+
|
12
|
+
TESTS = test-data-pool
|
13
|
+
|
14
|
+
check_PROGRAMS = test-data-pool
|
15
|
+
|
16
|
+
test_data_pool_SOURCES = data-pool.c data-pool.h
|
17
|
+
test_data_pool_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/t -DTEST_DATA_POOL
|
18
|
+
test_data_pool_LDADD = $(top_srcdir)/t/libmmdbtest.la \
|
19
|
+
$(top_srcdir)/t/libtap/libtap.a
|
20
|
+
|
21
|
+
$(top_srcdir)/t/libmmdbtest.la:
|
22
|
+
$(MAKE) -C $(top_srcdir)/t libmmdbtest.la
|
23
|
+
|
24
|
+
$(top_srcdir)/t/libtap/libtap.a:
|
25
|
+
$(MAKE) -C $(top_srcdir)/t/libtap libtap.a
|
@@ -0,0 +1,180 @@
|
|
1
|
+
#include "data-pool.h"
|
2
|
+
#include "maxminddb.h"
|
3
|
+
|
4
|
+
#include <stdbool.h>
|
5
|
+
#include <stddef.h>
|
6
|
+
#include <stdlib.h>
|
7
|
+
|
8
|
+
static bool can_multiply(size_t const, size_t const, size_t const);
|
9
|
+
|
10
|
+
// Allocate an MMDB_data_pool_s. It initially has space for size
|
11
|
+
// MMDB_entry_data_list_s structs.
|
12
|
+
MMDB_data_pool_s *data_pool_new(size_t const size)
|
13
|
+
{
|
14
|
+
MMDB_data_pool_s *const pool = calloc(1, sizeof(MMDB_data_pool_s));
|
15
|
+
if (!pool) {
|
16
|
+
return NULL;
|
17
|
+
}
|
18
|
+
|
19
|
+
if (size == 0 ||
|
20
|
+
!can_multiply(SIZE_MAX, size, sizeof(MMDB_entry_data_list_s))) {
|
21
|
+
data_pool_destroy(pool);
|
22
|
+
return NULL;
|
23
|
+
}
|
24
|
+
pool->size = size;
|
25
|
+
pool->blocks[0] = calloc(pool->size, sizeof(MMDB_entry_data_list_s));
|
26
|
+
if (!pool->blocks[0]) {
|
27
|
+
data_pool_destroy(pool);
|
28
|
+
return NULL;
|
29
|
+
}
|
30
|
+
pool->blocks[0]->pool = pool;
|
31
|
+
|
32
|
+
pool->sizes[0] = size;
|
33
|
+
|
34
|
+
pool->block = pool->blocks[0];
|
35
|
+
|
36
|
+
return pool;
|
37
|
+
}
|
38
|
+
|
39
|
+
// Determine if we can multiply m*n. We can do this if the result will be below
|
40
|
+
// the given max. max will typically be SIZE_MAX.
|
41
|
+
//
|
42
|
+
// We want to know if we'll wrap around.
|
43
|
+
static bool can_multiply(size_t const max, size_t const m, size_t const n)
|
44
|
+
{
|
45
|
+
if (m == 0) {
|
46
|
+
return false;
|
47
|
+
}
|
48
|
+
|
49
|
+
return n <= max / m;
|
50
|
+
}
|
51
|
+
|
52
|
+
// Clean up the data pool.
|
53
|
+
void data_pool_destroy(MMDB_data_pool_s *const pool)
|
54
|
+
{
|
55
|
+
if (!pool) {
|
56
|
+
return;
|
57
|
+
}
|
58
|
+
|
59
|
+
for (size_t i = 0; i <= pool->index; i++) {
|
60
|
+
free(pool->blocks[i]);
|
61
|
+
}
|
62
|
+
|
63
|
+
free(pool);
|
64
|
+
}
|
65
|
+
|
66
|
+
// Claim a new struct from the pool. Doing this may cause the pool's size to
|
67
|
+
// grow.
|
68
|
+
MMDB_entry_data_list_s *data_pool_alloc(MMDB_data_pool_s *const pool)
|
69
|
+
{
|
70
|
+
if (!pool) {
|
71
|
+
return NULL;
|
72
|
+
}
|
73
|
+
|
74
|
+
if (pool->used < pool->size) {
|
75
|
+
MMDB_entry_data_list_s *const element = pool->block + pool->used;
|
76
|
+
pool->used++;
|
77
|
+
return element;
|
78
|
+
}
|
79
|
+
|
80
|
+
// Take it from a new block of memory.
|
81
|
+
|
82
|
+
size_t const new_index = pool->index + 1;
|
83
|
+
if (new_index == DATA_POOL_NUM_BLOCKS) {
|
84
|
+
// See the comment about not growing this on DATA_POOL_NUM_BLOCKS.
|
85
|
+
return NULL;
|
86
|
+
}
|
87
|
+
|
88
|
+
if (!can_multiply(SIZE_MAX, pool->size, 2)) {
|
89
|
+
return NULL;
|
90
|
+
}
|
91
|
+
size_t const new_size = pool->size * 2;
|
92
|
+
|
93
|
+
if (!can_multiply(SIZE_MAX, new_size, sizeof(MMDB_entry_data_list_s))) {
|
94
|
+
return NULL;
|
95
|
+
}
|
96
|
+
pool->blocks[new_index] = calloc(new_size, sizeof(MMDB_entry_data_list_s));
|
97
|
+
if (!pool->blocks[new_index]) {
|
98
|
+
return NULL;
|
99
|
+
}
|
100
|
+
|
101
|
+
// We don't need to set this, but it's useful for introspection in tests.
|
102
|
+
pool->blocks[new_index]->pool = pool;
|
103
|
+
|
104
|
+
pool->index = new_index;
|
105
|
+
pool->block = pool->blocks[pool->index];
|
106
|
+
|
107
|
+
pool->size = new_size;
|
108
|
+
pool->sizes[pool->index] = pool->size;
|
109
|
+
|
110
|
+
MMDB_entry_data_list_s *const element = pool->block;
|
111
|
+
pool->used = 1;
|
112
|
+
return element;
|
113
|
+
}
|
114
|
+
|
115
|
+
// Turn the structs in the array-like pool into a linked list.
|
116
|
+
//
|
117
|
+
// Before calling this function, the list isn't linked up.
|
118
|
+
MMDB_entry_data_list_s *data_pool_to_list(MMDB_data_pool_s *const pool)
|
119
|
+
{
|
120
|
+
if (!pool) {
|
121
|
+
return NULL;
|
122
|
+
}
|
123
|
+
|
124
|
+
if (pool->index == 0 && pool->used == 0) {
|
125
|
+
return NULL;
|
126
|
+
}
|
127
|
+
|
128
|
+
for (size_t i = 0; i <= pool->index; i++) {
|
129
|
+
MMDB_entry_data_list_s *const block = pool->blocks[i];
|
130
|
+
|
131
|
+
size_t size = pool->sizes[i];
|
132
|
+
if (i == pool->index) {
|
133
|
+
size = pool->used;
|
134
|
+
}
|
135
|
+
|
136
|
+
for (size_t j = 0; j < size - 1; j++) {
|
137
|
+
MMDB_entry_data_list_s *const cur = block + j;
|
138
|
+
cur->next = block + j + 1;
|
139
|
+
}
|
140
|
+
|
141
|
+
if (i < pool->index) {
|
142
|
+
MMDB_entry_data_list_s *const last = block + size - 1;
|
143
|
+
last->next = pool->blocks[i + 1];
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
147
|
+
return pool->blocks[0];
|
148
|
+
}
|
149
|
+
|
150
|
+
#ifdef TEST_DATA_POOL
|
151
|
+
|
152
|
+
#include <libtap/tap.h>
|
153
|
+
#include <maxminddb_test_helper.h>
|
154
|
+
|
155
|
+
static void test_can_multiply(void);
|
156
|
+
|
157
|
+
int main(void)
|
158
|
+
{
|
159
|
+
plan(NO_PLAN);
|
160
|
+
test_can_multiply();
|
161
|
+
done_testing();
|
162
|
+
}
|
163
|
+
|
164
|
+
static void test_can_multiply(void)
|
165
|
+
{
|
166
|
+
{
|
167
|
+
ok(can_multiply(SIZE_MAX, 1, SIZE_MAX), "1*SIZE_MAX is ok");
|
168
|
+
}
|
169
|
+
|
170
|
+
{
|
171
|
+
ok(!can_multiply(SIZE_MAX, 2, SIZE_MAX), "2*SIZE_MAX is not ok");
|
172
|
+
}
|
173
|
+
|
174
|
+
{
|
175
|
+
ok(can_multiply(SIZE_MAX, 10240, sizeof(MMDB_entry_data_list_s)),
|
176
|
+
"1024 entry_data_list_s's are okay");
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
#endif
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#ifndef DATA_POOL_H
|
2
|
+
#define DATA_POOL_H
|
3
|
+
|
4
|
+
#include "maxminddb.h"
|
5
|
+
|
6
|
+
#include <stdbool.h>
|
7
|
+
#include <stddef.h>
|
8
|
+
|
9
|
+
// This should be large enough that we never need to grow the array of pointers
|
10
|
+
// to blocks. 32 is enough. Even starting out of with size 1 (1 struct), the
|
11
|
+
// 32nd element alone will provide 2**32 structs as we exponentially increase
|
12
|
+
// the number in each block. Being confident that we do not have to grow the
|
13
|
+
// array lets us avoid writing code to do that. That code would be risky as it
|
14
|
+
// would rarely be hit and likely not be well tested.
|
15
|
+
#define DATA_POOL_NUM_BLOCKS 32
|
16
|
+
|
17
|
+
// A pool of memory for MMDB_entry_data_list_s structs. This is so we can
|
18
|
+
// allocate multiple up front rather than one at a time for performance
|
19
|
+
// reasons.
|
20
|
+
//
|
21
|
+
// The order you add elements to it (by calling data_pool_alloc()) ends up as
|
22
|
+
// the order of the list.
|
23
|
+
//
|
24
|
+
// The memory only grows. There is no support for releasing an element you take
|
25
|
+
// back to the pool.
|
26
|
+
typedef struct MMDB_data_pool_s {
|
27
|
+
// Index of the current block we're allocating out of.
|
28
|
+
size_t index;
|
29
|
+
|
30
|
+
// The size of the current block, counting by structs.
|
31
|
+
size_t size;
|
32
|
+
|
33
|
+
// How many used in the current block, counting by structs.
|
34
|
+
size_t used;
|
35
|
+
|
36
|
+
// The current block we're allocating out of.
|
37
|
+
MMDB_entry_data_list_s *block;
|
38
|
+
|
39
|
+
// The size of each block.
|
40
|
+
size_t sizes[DATA_POOL_NUM_BLOCKS];
|
41
|
+
|
42
|
+
// An array of pointers to blocks of memory holding space for list
|
43
|
+
// elements.
|
44
|
+
MMDB_entry_data_list_s *blocks[DATA_POOL_NUM_BLOCKS];
|
45
|
+
} MMDB_data_pool_s;
|
46
|
+
|
47
|
+
MMDB_data_pool_s *data_pool_new(size_t const);
|
48
|
+
void data_pool_destroy(MMDB_data_pool_s *const);
|
49
|
+
MMDB_entry_data_list_s *data_pool_alloc(MMDB_data_pool_s *const);
|
50
|
+
MMDB_entry_data_list_s *data_pool_to_list(MMDB_data_pool_s *const);
|
51
|
+
|
52
|
+
#endif
|