filedictrb 0.1.1 → 0.1.4
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 +4 -4
- data/ext/filedict/filedict.h +53 -9
- data/ext/filedictrb/hash.c +2 -6
- data/lib/filedict/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f023c0d5acca6fc0f6355bae7c34f61eb5682f9f4652f83dd8befefac6f2c050
|
4
|
+
data.tar.gz: de7ba4f1fcf57e21771312bf9bb8daacdfc39a044e9ef263a81494bb6e976dca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2cb1f1f1a43a0494aa95f8d31d0b1b490f63ce07c57bcc1e6af2003064656784034064cebefd8247b886174e3e57c600c4464e2eba69a61cf7720c6cee9fcc1e
|
7
|
+
data.tar.gz: 3f4f4dbf014f9af21ad104a3282f09ce7d07c22f70c60e5e33b43c58159bb403567e42116896091062a527bd881524d15db9b8724a16065395b0cdd6cdb715c1
|
data/ext/filedict/filedict.h
CHANGED
@@ -27,6 +27,7 @@ typedef size_t (*filedict_hash_function_t)(const char *);
|
|
27
27
|
typedef struct filedict_t {
|
28
28
|
const char *error;
|
29
29
|
int fd;
|
30
|
+
int flags;
|
30
31
|
void *data;
|
31
32
|
size_t data_len;
|
32
33
|
filedict_hash_function_t hash_function;
|
@@ -38,7 +39,7 @@ typedef struct filedict_header_t {
|
|
38
39
|
} __attribute__ ((__packed__)) filedict_header_t;
|
39
40
|
|
40
41
|
typedef struct filedict_read_t {
|
41
|
-
|
42
|
+
filedict_t *filedict;
|
42
43
|
const char *key;
|
43
44
|
const char *value;
|
44
45
|
filedict_bucket_t *bucket;
|
@@ -96,6 +97,7 @@ static size_t filedict_copy_string(char *dest, const char *src, size_t max_len)
|
|
96
97
|
static void filedict_init(filedict_t *filedict) {
|
97
98
|
filedict->error = NULL;
|
98
99
|
filedict->fd = 0;
|
100
|
+
filedict->flags = 0;
|
99
101
|
filedict->data_len = 0;
|
100
102
|
filedict->data = NULL;
|
101
103
|
filedict->hash_function = filedict_default_hash_function;
|
@@ -110,6 +112,7 @@ static void filedict_deinit(filedict_t *filedict) {
|
|
110
112
|
if (filedict->fd) {
|
111
113
|
close(filedict->fd);
|
112
114
|
filedict->fd = 0;
|
115
|
+
filedict->flags = 0;
|
113
116
|
}
|
114
117
|
}
|
115
118
|
|
@@ -128,6 +131,28 @@ static size_t filedict_file_size(size_t initial_bucket_count, size_t hashmap_cou
|
|
128
131
|
return result;
|
129
132
|
}
|
130
133
|
|
134
|
+
/*
|
135
|
+
* Resizes the filedict based on the header hashmap count and initial bucket count.
|
136
|
+
* Naturally, your pointers into the map will become invalid after calling this.
|
137
|
+
*/
|
138
|
+
static void filedict_resize(filedict_t *filedict) {
|
139
|
+
filedict_header_t *header = (filedict_header_t*)filedict->data;
|
140
|
+
size_t computed_size = filedict_file_size(header->initial_bucket_count, header->hashmap_count);
|
141
|
+
if (computed_size <= filedict->data_len) return;
|
142
|
+
|
143
|
+
munmap(filedict->data, filedict->data_len);
|
144
|
+
filedict->data = mmap(
|
145
|
+
filedict->data,
|
146
|
+
computed_size,
|
147
|
+
PROT_READ | ((filedict->flags & O_RDWR) ? PROT_WRITE : 0),
|
148
|
+
MAP_SHARED,
|
149
|
+
filedict->fd,
|
150
|
+
0
|
151
|
+
);
|
152
|
+
if (filedict->data == MAP_FAILED) { filedict->error = strerror(errno); return; }
|
153
|
+
filedict->data_len = computed_size;
|
154
|
+
}
|
155
|
+
|
131
156
|
/*
|
132
157
|
* This opens a new file for reading and writing, optionally letting you specify the initial bucket count.
|
133
158
|
*/
|
@@ -146,15 +171,24 @@ static void filedict_open_f(
|
|
146
171
|
int flags,
|
147
172
|
unsigned int initial_bucket_count
|
148
173
|
) {
|
174
|
+
struct stat info;
|
175
|
+
|
176
|
+
filedict->flags = flags;
|
149
177
|
filedict->fd = open(filename, flags, 0666);
|
150
178
|
if (filedict->fd == -1) { filedict->error = strerror(errno); return; }
|
179
|
+
if (fstat(filedict->fd, &info) != 0) { filedict->error = strerror(errno); return; }
|
180
|
+
|
181
|
+
if (info.st_size == 0 && (flags & O_RDWR)) {
|
182
|
+
filedict->data_len = filedict_file_size(initial_bucket_count, 1);
|
183
|
+
ftruncate(filedict->fd, filedict->data_len);
|
184
|
+
} else {
|
185
|
+
filedict->data_len = info.st_size;
|
186
|
+
}
|
151
187
|
|
152
|
-
filedict->data_len = filedict_file_size(initial_bucket_count, 1);
|
153
|
-
ftruncate(filedict->fd, filedict->data_len);
|
154
188
|
filedict->data = mmap(
|
155
189
|
NULL,
|
156
190
|
filedict->data_len,
|
157
|
-
PROT_READ | PROT_WRITE,
|
191
|
+
PROT_READ | ((flags & O_RDWR) ? PROT_WRITE : 0),
|
158
192
|
MAP_SHARED,
|
159
193
|
filedict->fd,
|
160
194
|
0
|
@@ -163,8 +197,11 @@ static void filedict_open_f(
|
|
163
197
|
|
164
198
|
filedict_header_t *data = (filedict_header_t *)filedict->data;
|
165
199
|
assert(initial_bucket_count <= UINT_MAX);
|
166
|
-
|
167
|
-
data->
|
200
|
+
|
201
|
+
if (data->initial_bucket_count == 0) {
|
202
|
+
data->initial_bucket_count = initial_bucket_count;
|
203
|
+
data->hashmap_count = 1;
|
204
|
+
}
|
168
205
|
}
|
169
206
|
|
170
207
|
/*
|
@@ -272,7 +309,7 @@ try_again:
|
|
272
309
|
filedict->data = mmap(
|
273
310
|
filedict->data,
|
274
311
|
new_data_len,
|
275
|
-
PROT_READ | PROT_WRITE,
|
312
|
+
PROT_READ | ((filedict->flags & O_RDWR) ? PROT_WRITE : 0),
|
276
313
|
MAP_SHARED,
|
277
314
|
filedict->fd,
|
278
315
|
0
|
@@ -353,7 +390,7 @@ static int filedict_read_advance_entry(filedict_read_t *read) {
|
|
353
390
|
* Returns 0 when there are no more hashmaps, or the latest hashmap has no matching entries.
|
354
391
|
*/
|
355
392
|
static int filedict_read_advance_hashmap(filedict_read_t *read) {
|
356
|
-
|
393
|
+
filedict_t *filedict = read->filedict;
|
357
394
|
|
358
395
|
assert(filedict);
|
359
396
|
assert(filedict->data);
|
@@ -363,6 +400,13 @@ static int filedict_read_advance_hashmap(filedict_read_t *read) {
|
|
363
400
|
if (read->hashmap_i >= header->hashmap_count) log_return(0);
|
364
401
|
|
365
402
|
size_t offset = filedict_file_size(header->initial_bucket_count, read->hashmap_i);
|
403
|
+
|
404
|
+
if (offset >= filedict->data_len) {
|
405
|
+
filedict_resize(filedict);
|
406
|
+
if (filedict->error) log_return(0);
|
407
|
+
header = (filedict_header_t*)filedict->data;
|
408
|
+
}
|
409
|
+
|
366
410
|
filedict_bucket_t *hashmap = filedict->data + offset;
|
367
411
|
|
368
412
|
read->bucket_count = (size_t)header->initial_bucket_count << read->hashmap_i;
|
@@ -377,7 +421,7 @@ static int filedict_read_advance_hashmap(filedict_read_t *read) {
|
|
377
421
|
/*
|
378
422
|
* Returns a "read" at the given key. If there's a hit, <return>.value will have the value.
|
379
423
|
*/
|
380
|
-
static filedict_read_t filedict_get(
|
424
|
+
static filedict_read_t filedict_get(filedict_t *filedict, const char *key) {
|
381
425
|
filedict_read_t read;
|
382
426
|
read.filedict = filedict;
|
383
427
|
read.key = key;
|
data/ext/filedictrb/hash.c
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
|
4
4
|
extern VALUE mFiledict;
|
5
5
|
VALUE cHash;
|
6
|
-
VALUE mSetExt;
|
7
6
|
VALUE cSet;
|
8
7
|
|
9
8
|
ID id_add;
|
@@ -89,7 +88,7 @@ static VALUE fd_set_add(int argc, VALUE *argv, VALUE self) {
|
|
89
88
|
VALUE fd_hash_ruby_object = rb_ivar_get(self, id_fd_hash);
|
90
89
|
|
91
90
|
if (fd_hash_ruby_object == Qnil) {
|
92
|
-
return
|
91
|
+
return rb_call_super(argc, argv);
|
93
92
|
}
|
94
93
|
|
95
94
|
fd_hash_t *fd_hash = RTYPEDDATA_DATA(fd_hash_ruby_object);
|
@@ -124,8 +123,6 @@ static VALUE fd_hash_access(VALUE self, VALUE key) {
|
|
124
123
|
rb_ivar_set(result, id_fd_hash, self);
|
125
124
|
rb_ivar_set(result, id_fd_key, key);
|
126
125
|
|
127
|
-
rb_extend_object(result, mSetExt);
|
128
|
-
|
129
126
|
return result;
|
130
127
|
}
|
131
128
|
|
@@ -139,9 +136,8 @@ void fdrb_init_hash() {
|
|
139
136
|
|
140
137
|
VALUE rb_cSet = rb_define_class("Set", rb_cObject);
|
141
138
|
cSet = rb_define_class_under(mFiledict, "Set", rb_cSet);
|
142
|
-
mSetExt = rb_define_module_under(mFiledict, "SetExt");
|
143
139
|
|
144
|
-
rb_define_method(
|
140
|
+
rb_define_method(cSet, "add", fd_set_add, -1);
|
145
141
|
|
146
142
|
id_add = rb_intern("add");
|
147
143
|
id_remove = rb_intern("remove");
|
data/lib/filedict/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: filedictrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nigel Baillie
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -58,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
58
|
- !ruby/object:Gem::Version
|
59
59
|
version: '0'
|
60
60
|
requirements: []
|
61
|
-
rubygems_version: 3.
|
61
|
+
rubygems_version: 3.1.6
|
62
62
|
signing_key:
|
63
63
|
specification_version: 4
|
64
64
|
summary: Uses filedict to emulate a file-backed Hash<Set<String>>
|