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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64d09435d5e09d917e12a06932a75ddf365b081a9caa1253a3b11a53a235196c
4
- data.tar.gz: 4cd1fedaa0035da30c2d9572eb28dd190cab901803089b164c36ba4d5776d36c
3
+ metadata.gz: f023c0d5acca6fc0f6355bae7c34f61eb5682f9f4652f83dd8befefac6f2c050
4
+ data.tar.gz: de7ba4f1fcf57e21771312bf9bb8daacdfc39a044e9ef263a81494bb6e976dca
5
5
  SHA512:
6
- metadata.gz: d232d34e3b99221baf055c56ca672b2536d910103a3a4dd6bab1be9005270db86cda72690f1dd56ed230fb0214ef4cecae45a9f8ae5931b7ebcb3288df8492e2
7
- data.tar.gz: de03f2dc36efad352a54f647f3275cc15bae641799e3b2ca258cdbb08100103493ac35e2c37e327f7f39feb2dc92eb80af6fb3c4cd645fad8794612ee0cffcfc
6
+ metadata.gz: 2cb1f1f1a43a0494aa95f8d31d0b1b490f63ce07c57bcc1e6af2003064656784034064cebefd8247b886174e3e57c600c4464e2eba69a61cf7720c6cee9fcc1e
7
+ data.tar.gz: 3f4f4dbf014f9af21ad104a3282f09ce7d07c22f70c60e5e33b43c58159bb403567e42116896091062a527bd881524d15db9b8724a16065395b0cdd6cdb715c1
@@ -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
- const filedict_t *filedict;
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
- data->initial_bucket_count = initial_bucket_count;
167
- data->hashmap_count = 1;
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
- const filedict_t *filedict = read->filedict;
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(const filedict_t *filedict, const char *key) {
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;
@@ -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 self;
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(mSetExt, "add", fd_set_add, -1);
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");
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Filedict
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.4"
5
5
  end
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.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-03-30 00:00:00.000000000 Z
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.3.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>>