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 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>>