filedictrb 0.1.1 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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>>
|