prometheus-client-mmap 0.7.0.beta41 → 0.7.0.beta42

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,6 @@
3
3
  #include <ruby.h>
4
4
  #include <file_parsing.h>
5
5
 
6
- VALUE entries_to_string(entry_struct **sorted_entries, size_t entries_count);
6
+ int entries_to_string(VALUE string, entry_t **sorted_entries, size_t entries_count);
7
7
 
8
- #endif
8
+ #endif
@@ -1,7 +1,8 @@
1
1
  #include <ruby.h>
2
+
2
3
  #include "utils.h"
3
4
 
4
- void save_exception(VALUE exception, const char *fmt, ...){
5
+ void save_exception(VALUE exception, const char *fmt, ...) {
5
6
  va_list args;
6
7
 
7
8
  va_start(args, fmt);
@@ -13,7 +14,7 @@ void save_exception(VALUE exception, const char *fmt, ...){
13
14
  rb_thread_local_aset(current_thread, rb_intern("prometheus_last_exception_message"), message);
14
15
  }
15
16
 
16
- void raise_last_exception(){
17
+ NORETURN(void raise_last_exception()) {
17
18
  VALUE current_thread = rb_thread_current();
18
19
  VALUE exception = rb_thread_local_aref(current_thread, rb_intern("prometheus_last_exception"));
19
20
  VALUE message = rb_thread_local_aref(current_thread, rb_intern("prometheus_last_exception_message"));
@@ -20,7 +20,7 @@
20
20
  __typeof__ (b) _b = (b); \
21
21
  _a > _b ? _a : _b; })
22
22
 
23
- void raise_last_exception();
23
+ NORETURN(void raise_last_exception());
24
24
  void save_exception(VALUE exception, const char *fmt, ...);
25
25
 
26
26
  #endif
@@ -1,16 +1,16 @@
1
1
  #include <ruby.h>
2
2
  #include <ruby/intern.h>
3
3
 
4
+ #include <errno.h>
5
+ #include <fcntl.h>
4
6
  #include <sys/mman.h>
5
7
  #include <unistd.h>
6
- #include <fcntl.h>
7
- #include <errno.h>
8
8
 
9
9
  #include "file_format.h"
10
10
  #include "mmap.h"
11
11
  #include "value_access.h"
12
12
 
13
- int open_and_extend_file(mm_ipc *i_mm, size_t len) {
13
+ static int open_and_extend_file(mm_ipc *i_mm, size_t len) {
14
14
  int fd;
15
15
 
16
16
  if ((fd = open(i_mm->t->path, i_mm->t->smode)) == -1) {
@@ -30,7 +30,7 @@ int open_and_extend_file(mm_ipc *i_mm, size_t len) {
30
30
  return fd;
31
31
  }
32
32
 
33
- void expand(mm_ipc *i_mm, size_t len) {
33
+ static void expand(mm_ipc *i_mm, size_t len) {
34
34
  if (len < i_mm->t->len) {
35
35
  rb_raise(rb_eArgError, "Can't reduce the size of mmap");
36
36
  }
@@ -59,7 +59,7 @@ void expand(mm_ipc *i_mm, size_t len) {
59
59
  i_mm->t->real = len;
60
60
  }
61
61
 
62
- void save_entry(mm_ipc *i_mm, uint32_t offset, VALUE key, VALUE value){
62
+ static void save_entry(mm_ipc *i_mm, size_t offset, VALUE key, VALUE value) {
63
63
  uint32_t key_length = (uint32_t)RSTRING_LEN(key);
64
64
 
65
65
  char *pos = (char *)i_mm->t->addr + offset;
@@ -70,59 +70,56 @@ void save_entry(mm_ipc *i_mm, uint32_t offset, VALUE key, VALUE value){
70
70
  memmove(pos, StringValuePtr(key), key_length);
71
71
  pos += key_length;
72
72
 
73
- memset(pos, ' ', padding_length(key_length));
73
+ memset(pos, ' ', padding_length(key_length)); // TODO: considder padding with /0
74
74
  pos += padding_length(key_length);
75
75
 
76
76
  double val = NUM2DBL(value);
77
77
  memcpy(pos, &val, sizeof(double));
78
78
  }
79
79
 
80
- inline uint32_t load_used(mm_ipc *i_mm) {
81
- uint32_t used = *((uint32_t *)i_mm->t->addr);
82
-
83
- if (used == 0) {
84
- used = START_POSITION;
80
+ static void save_value(mm_ipc *i_mm, VALUE _offset, VALUE value) {
81
+ Check_Type(_offset, T_FIXNUM);
82
+ size_t offset = NUM2UINT(_offset);
83
+ if ((i_mm->t->real + sizeof(double)) <= offset) {
84
+ rb_raise(rb_eIndexError, "offset %zu out of string", offset);
85
85
  }
86
- return used;
87
- }
88
86
 
89
- inline void save_used(mm_ipc *i_mm, uint32_t used) {
90
- *((uint32_t *)i_mm->t->addr) = used;
91
- }
87
+ if (i_mm->t->flag & MM_FROZEN) {
88
+ rb_error_frozen("mmap");
89
+ }
92
90
 
93
- VALUE method_load_used(VALUE self) {
94
- mm_ipc *i_mm;
91
+ char *pos = (char *)i_mm->t->addr + offset;
95
92
 
96
- GET_MMAP(self, i_mm, MM_MODIFY);
97
- return UINT2NUM(load_used(i_mm));
93
+ double val = NUM2DBL(value);
94
+ memcpy(pos, &val, sizeof(double));
98
95
  }
99
96
 
100
- VALUE method_save_used(VALUE self, VALUE value) {
101
- Check_Type(value, T_FIXNUM);
102
- mm_ipc *i_mm;
103
-
104
- GET_MMAP(self, i_mm, MM_MODIFY);
105
-
106
- if (i_mm->t->len < INITIAL_SIZE) {
107
- expand(i_mm, INITIAL_SIZE);
97
+ static VALUE load_value(mm_ipc *i_mm, VALUE _offset) {
98
+ Check_Type(_offset, T_FIXNUM);
99
+ size_t offset = NUM2UINT(_offset);
100
+ if ((i_mm->t->real + sizeof(double)) <= offset) {
101
+ rb_raise(rb_eIndexError, "offset %zu out of string", offset);
108
102
  }
109
103
 
110
- save_used(i_mm, NUM2UINT(value));
111
- return value;
104
+ char *pos = (char *)i_mm->t->addr + offset;
105
+
106
+ double value;
107
+ memcpy(&value, pos, sizeof(double));
108
+ return DBL2NUM(value);
112
109
  }
113
110
 
114
- VALUE method_add_entry(VALUE self, VALUE positions, VALUE key, VALUE value) {
115
- Check_Type(positions, T_HASH);
116
- Check_Type(key, T_STRING);
111
+ inline uint32_t load_used(mm_ipc *i_mm) {
112
+ uint32_t used = *((uint32_t *)i_mm->t->addr);
117
113
 
118
- VALUE position = rb_hash_lookup(positions, key);
119
- if (position != Qnil){
120
- return position;
114
+ if (used == 0) {
115
+ used = START_POSITION;
121
116
  }
117
+ return used;
118
+ }
122
119
 
123
- mm_ipc *i_mm;
124
- GET_MMAP(self, i_mm, MM_MODIFY);
120
+ inline void save_used(mm_ipc *i_mm, uint32_t used) { *((uint32_t *)i_mm->t->addr) = used; }
125
121
 
122
+ static VALUE initialize_entry(mm_ipc *i_mm, VALUE positions, VALUE key, VALUE value) {
126
123
  if (i_mm->t->flag & MM_FROZEN) {
127
124
  rb_error_frozen("mmap");
128
125
  }
@@ -139,25 +136,68 @@ VALUE method_add_entry(VALUE self, VALUE positions, VALUE key, VALUE value) {
139
136
  while (i_mm->t->len < (used + entry_length)) {
140
137
  expand(i_mm, i_mm->t->len * 2);
141
138
  }
142
-
143
139
  save_entry(i_mm, used, key, value);
144
140
  save_used(i_mm, used + entry_length);
141
+
145
142
  return rb_hash_aset(positions, key, INT2NUM(used + value_offset));
146
143
  }
147
144
 
148
- VALUE method_get_double(VALUE self, VALUE index) {
145
+ VALUE method_fetch_entry(VALUE self, VALUE positions, VALUE key, VALUE default_value) {
146
+ Check_Type(positions, T_HASH);
147
+ Check_Type(key, T_STRING);
148
+
149
+ mm_ipc *i_mm;
150
+ GET_MMAP(self, i_mm, MM_MODIFY);
151
+
152
+ VALUE position = rb_hash_lookup(positions, key);
153
+
154
+ if (position != Qnil) {
155
+ return load_value(i_mm, position);
156
+ }
157
+
158
+ position = initialize_entry(i_mm, positions, key, default_value);
159
+ return load_value(i_mm, position);
160
+ }
161
+
162
+ VALUE method_upsert_entry(VALUE self, VALUE positions, VALUE key, VALUE value) {
163
+ Check_Type(positions, T_HASH);
164
+ Check_Type(key, T_STRING);
165
+
166
+ mm_ipc *i_mm;
167
+ GET_MMAP(self, i_mm, MM_MODIFY);
168
+
169
+ VALUE position = rb_hash_lookup(positions, key);
170
+
171
+ if (position != Qnil) {
172
+ save_value(i_mm, position, value);
173
+ return load_value(i_mm, position);
174
+ }
175
+
176
+ position = initialize_entry(i_mm, positions, key, value);
177
+ return load_value(i_mm, position);
178
+ }
179
+
180
+ VALUE method_load_used(VALUE self) {
149
181
  mm_ipc *i_mm;
182
+
150
183
  GET_MMAP(self, i_mm, MM_MODIFY);
184
+ return UINT2NUM(load_used(i_mm));
185
+ }
186
+
187
+ VALUE method_save_used(VALUE self, VALUE value) {
188
+ Check_Type(value, T_FIXNUM);
189
+ mm_ipc *i_mm;
151
190
 
152
- Check_Type(index, T_FIXNUM);
153
- size_t idx = NUM2UINT(index);
191
+ GET_MMAP(self, i_mm, MM_MODIFY);
154
192
 
155
- if ((i_mm->t->real + sizeof(double)) <= idx) {
156
- rb_raise(rb_eIndexError, "index %zu out of string", idx);
193
+ if (i_mm->t->flag & MM_FROZEN) {
194
+ rb_error_frozen("mmap");
157
195
  }
158
196
 
159
- double tmp;
197
+ if (i_mm->t->len < INITIAL_SIZE) {
198
+ expand(i_mm, INITIAL_SIZE);
199
+ }
160
200
 
161
- memcpy(&tmp, (char *)i_mm->t->addr + idx, sizeof(double));
162
- return DBL2NUM(tmp);
163
- }
201
+ save_used(i_mm, NUM2UINT(value));
202
+ return value;
203
+ }
@@ -5,8 +5,10 @@ VALUE method_load_used(VALUE self);
5
5
 
6
6
  VALUE method_save_used(VALUE self, VALUE value);
7
7
 
8
- VALUE method_add_entry(VALUE self, VALUE positions, VALUE key, VALUE value);
9
-
10
8
  VALUE method_get_double(VALUE self, VALUE index);
11
9
 
10
+ VALUE method_fetch_entry(VALUE self, VALUE positions, VALUE key, VALUE default_value);
11
+
12
+ VALUE method_upsert_entry(VALUE self, VALUE positions, VALUE key, VALUE value);
13
+
12
14
  #endif
Binary file
@@ -27,7 +27,7 @@ module Prometheus
27
27
  end
28
28
 
29
29
  def pid
30
- parts[2..-1].join('_')
30
+ (parts[2..-1] || []).join('_')
31
31
  end
32
32
 
33
33
  def multiprocess_mode
@@ -1,18 +1,16 @@
1
1
  require 'prometheus/client/helper/entry_parser'
2
2
  require 'prometheus/client/helper/file_locker'
3
3
  require 'fast_mmaped_file'
4
- require 'mmap'
5
4
 
6
5
  module Prometheus
7
6
  module Client
8
7
  module Helper
9
- class MmapedFile < Mmap
8
+ class MmapedFile < FastMmapedFile
10
9
  include EntryParser
11
- include FastMmapedFile
12
10
 
13
11
  attr_reader :filepath, :size
14
12
 
15
- def initialize(filepath, mode = 'r', protection = Mmap::MAP_SHARED, options = {})
13
+ def initialize(filepath)
16
14
  @filepath = filepath
17
15
 
18
16
  File.open(filepath, 'a+b') do |file|
@@ -20,7 +18,7 @@ module Prometheus
20
18
  @size = file.size
21
19
  end
22
20
 
23
- super(filepath, mode, protection, options)
21
+ super(filepath)
24
22
  end
25
23
 
26
24
  def close
@@ -37,7 +35,7 @@ module Prometheus
37
35
 
38
36
  class << self
39
37
  def open(filepath)
40
- MmapedFile.new(filepath, 'rw', Mmap::MAP_SHARED)
38
+ MmapedFile.new(filepath)
41
39
  end
42
40
 
43
41
  def ensure_exclusive_file(file_prefix = 'mmaped_file')
@@ -8,7 +8,7 @@ module Prometheus
8
8
  include EntryParser
9
9
  attr_reader :filepath
10
10
 
11
- def data
11
+ def source
12
12
  @data ||= File.read(filepath, mode: 'rb')
13
13
  end
14
14
 
@@ -17,11 +17,11 @@ module Prometheus
17
17
  end
18
18
 
19
19
  def slice(*args)
20
- data.slice(*args)
20
+ source.slice(*args)
21
21
  end
22
22
 
23
23
  def size
24
- data.length
24
+ source.length
25
25
  end
26
26
  end
27
27
  end
@@ -39,16 +39,11 @@ module Prometheus
39
39
  end
40
40
 
41
41
  def read_value(key)
42
- pos = @m.add_entry(@positions, key, 0.0)
43
-
44
- @m.get_double(pos)
42
+ @m.fetch_entry(@positions, key, 0.0)
45
43
  end
46
44
 
47
45
  def write_value(key, value)
48
- pos = @m.add_entry(@positions, key, 0.0)
49
-
50
- # pos = @positions[key]
51
- @m[pos..pos + 7] = [value].pack('d')
46
+ @m.upsert_entry(@positions, key, value)
52
47
  end
53
48
 
54
49
  def path
@@ -1,5 +1,4 @@
1
1
  require 'json'
2
- require 'mmap'
3
2
 
4
3
  module Prometheus
5
4
  module Client
@@ -12,6 +12,15 @@ module Prometheus
12
12
  end
13
13
 
14
14
  def self.worker_id
15
+ match = $0.match(/worker\[([^\]]+)\]/)
16
+ if match
17
+ match[1]
18
+ else
19
+ object_based_worker_id
20
+ end
21
+ end
22
+
23
+ def self.object_based_worker_id
15
24
  return unless defined?(::Unicorn::Worker)
16
25
 
17
26
  workers = ObjectSpace.each_object(::Unicorn::Worker)
@@ -1,5 +1,5 @@
1
1
  module Prometheus
2
2
  module Client
3
- VERSION = '0.7.0.beta41'.freeze
3
+ VERSION = '0.7.0.beta42'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prometheus-client-mmap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0.beta41
4
+ version: 0.7.0.beta42
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Schmidt
@@ -9,28 +9,8 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-11-30 00:00:00.000000000 Z
12
+ date: 2017-12-06 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: mmap2
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - "~>"
19
- - !ruby/object:Gem::Version
20
- version: '2.2'
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: 2.2.9
24
- type: :runtime
25
- prerelease: false
26
- version_requirements: !ruby/object:Gem::Requirement
27
- requirements:
28
- - - "~>"
29
- - !ruby/object:Gem::Version
30
- version: '2.2'
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 2.2.9
34
14
  - !ruby/object:Gem::Dependency
35
15
  name: fuzzbert
36
16
  requirement: !ruby/object:Gem::Requirement
@@ -112,9 +92,8 @@ files:
112
92
  - ext/fast_mmaped_file/file_reading.h
113
93
  - ext/fast_mmaped_file/globals.h
114
94
  - ext/fast_mmaped_file/hashmap.c
115
- - ext/fast_mmaped_file/hashmap.h
116
95
  - ext/fast_mmaped_file/jsmn.c
117
- - ext/fast_mmaped_file/jsmn.h
96
+ - ext/fast_mmaped_file/mmap.c
118
97
  - ext/fast_mmaped_file/mmap.h
119
98
  - ext/fast_mmaped_file/rendering.c
120
99
  - ext/fast_mmaped_file/rendering.h
@@ -150,7 +129,6 @@ files:
150
129
  - lib/prometheus/client/support/unicorn.rb
151
130
  - lib/prometheus/client/uses_value_type.rb
152
131
  - lib/prometheus/client/version.rb
153
- - lib/prometheus/client/version.rb.orig
154
132
  homepage: https://gitlab.com/gitlab-org/prometheus-client-mmap
155
133
  licenses:
156
134
  - Apache 2.0
@@ -1,266 +0,0 @@
1
- /*
2
- * Copyright (c) 2016-2017 David Leeds <davidesleeds@gmail.com>
3
- *
4
- * Hashmap is free software; you can redistribute it and/or modify
5
- * it under the terms of the MIT license. See LICENSE for details.
6
- */
7
-
8
- #ifndef __HASHMAP_H__
9
- #define __HASHMAP_H__
10
-
11
- #include <stddef.h>
12
-
13
- /*
14
- * Define HASHMAP_METRICS to compile in performance analysis
15
- * functions for use in assessing hash function performance.
16
- */
17
- /* #define HASHMAP_METRICS */
18
-
19
- /*
20
- * Define HASHMAP_NOASSERT to compile out all assertions used internally.
21
- */
22
- /* #define HASHMAP_NOASSERT */
23
-
24
- /*
25
- * Macros to declare type-specific versions of hashmap_*() functions to
26
- * allow compile-time type checking and avoid the need for type casting.
27
- */
28
- #define HASHMAP_FUNCS_DECLARE(name, key_type, data_type) \
29
- data_type *name##_hashmap_put(struct hashmap *map, key_type *key, \
30
- data_type *data); \
31
- data_type *name##_hashmap_get(const struct hashmap *map, \
32
- key_type *key); \
33
- data_type *name##_hashmap_remove(struct hashmap *map, \
34
- key_type *key); \
35
- key_type *name##_hashmap_iter_get_key( \
36
- const struct hashmap_iter *iter); \
37
- data_type *name##_hashmap_iter_get_data( \
38
- const struct hashmap_iter *iter); \
39
- void name##_hashmap_iter_set_data(const struct hashmap_iter *iter, \
40
- data_type *data); \
41
- int name##_hashmap_foreach(const struct hashmap *map, \
42
- int (*func)(key_type *, data_type *, void *), void *arg);
43
-
44
- #define HASHMAP_FUNCS_CREATE(name, key_type, data_type) \
45
- data_type *name##_hashmap_put(struct hashmap *map, key_type *key, \
46
- data_type *data) \
47
- { \
48
- return (data_type *)hashmap_put(map, (const void *)key, \
49
- (void *)data); \
50
- } \
51
- data_type *name##_hashmap_get(const struct hashmap *map, \
52
- key_type *key) \
53
- { \
54
- return (data_type *)hashmap_get(map, (const void *)key); \
55
- } \
56
- data_type *name##_hashmap_remove(struct hashmap *map, \
57
- key_type *key) \
58
- { \
59
- return (data_type *)hashmap_remove(map, (const void *)key); \
60
- } \
61
- key_type *name##_hashmap_iter_get_key( \
62
- const struct hashmap_iter *iter) \
63
- { \
64
- return (key_type *)hashmap_iter_get_key(iter); \
65
- } \
66
- data_type *name##_hashmap_iter_get_data( \
67
- const struct hashmap_iter *iter) \
68
- { \
69
- return (data_type *)hashmap_iter_get_data(iter); \
70
- } \
71
- void name##_hashmap_iter_set_data(const struct hashmap_iter *iter, \
72
- data_type *data) \
73
- { \
74
- hashmap_iter_set_data(iter, (void *)data); \
75
- } \
76
- struct __##name##_hashmap_foreach_state { \
77
- int (*func)(key_type *, data_type *, void *); \
78
- void *arg; \
79
- }; \
80
- static inline int __##name##_hashmap_foreach_callback(const void *key, \
81
- void *data, void *arg) \
82
- { \
83
- struct __##name##_hashmap_foreach_state *s = \
84
- (struct __##name##_hashmap_foreach_state *)arg; \
85
- return s->func((key_type *)key, (data_type *)data, s->arg); \
86
- } \
87
- int name##_hashmap_foreach(const struct hashmap *map, \
88
- int (*func)(key_type *, data_type *, void *), void *arg) \
89
- { \
90
- struct __##name##_hashmap_foreach_state s = { func, arg }; \
91
- return hashmap_foreach(map, \
92
- __##name##_hashmap_foreach_callback, &s); \
93
- }
94
-
95
-
96
- struct hashmap_iter;
97
- struct hashmap_entry;
98
-
99
- /*
100
- * The hashmap state structure.
101
- */
102
- struct hashmap {
103
- size_t table_size_init;
104
- size_t table_size;
105
- size_t num_entries;
106
- struct hashmap_entry *table;
107
- size_t (*hash)(const void *);
108
- int (*key_compare)(const void *, const void *);
109
- void *(*key_alloc)(const void *);
110
- void (*key_free)(void *);
111
- };
112
-
113
- /*
114
- * Initialize an empty hashmap. A hash function and a key comparator are
115
- * required.
116
- *
117
- * hash_func should return an even distribution of numbers between 0
118
- * and SIZE_MAX varying on the key provided.
119
- *
120
- * key_compare_func should return 0 if the keys match, and non-zero otherwise.
121
- *
122
- * initial_size is optional, and may be set to the max number of entries
123
- * expected to be put in the hash table. This is used as a hint to
124
- * pre-allocate the hash table to the minimum size to avoid gratuitous rehashes.
125
- * If initial_size 0, a default size will be used.
126
- *
127
- * Returns 0 on success and -errno on failure.
128
- */
129
- int hashmap_init(struct hashmap *map, size_t (*hash_func)(const void *),
130
- int (*key_compare_func)(const void *, const void *),
131
- size_t initial_size);
132
-
133
- /*
134
- * Free the hashmap and all associated memory.
135
- */
136
- void hashmap_destroy(struct hashmap *map);
137
-
138
- /*
139
- * Enable internal memory allocation and management of hash keys.
140
- */
141
- void hashmap_set_key_alloc_funcs(struct hashmap *map,
142
- void *(*key_alloc_func)(const void *),
143
- void (*key_free_func)(void *));
144
-
145
- /*
146
- * Add an entry to the hashmap. If an entry with a matching key already
147
- * exists and has a data pointer associated with it, the existing data
148
- * pointer is returned, instead of assigning the new value. Compare
149
- * the return value with the data passed in to determine if a new entry was
150
- * created. Returns NULL if memory allocation failed.
151
- */
152
- void *hashmap_put(struct hashmap *map, const void *key, void *data);
153
-
154
- /*
155
- * Return the data pointer, or NULL if no entry exists.
156
- */
157
- void *hashmap_get(const struct hashmap *map, const void *key);
158
-
159
- /*
160
- * Remove an entry with the specified key from the map.
161
- * Returns the data pointer, or NULL, if no entry was found.
162
- */
163
- void *hashmap_remove(struct hashmap *map, const void *key);
164
-
165
- /*
166
- * Remove all entries.
167
- */
168
- void hashmap_clear(struct hashmap *map);
169
-
170
- /*
171
- * Remove all entries and reset the hash table to its initial size.
172
- */
173
- void hashmap_reset(struct hashmap *map);
174
-
175
- /*
176
- * Return the number of entries in the hash map.
177
- */
178
- size_t hashmap_size(const struct hashmap *map);
179
-
180
- /*
181
- * Get a new hashmap iterator. The iterator is an opaque
182
- * pointer that may be used with hashmap_iter_*() functions.
183
- * Hashmap iterators are INVALID after a put or remove operation is performed.
184
- * hashmap_iter_remove() allows safe removal during iteration.
185
- */
186
- struct hashmap_iter *hashmap_iter(const struct hashmap *map);
187
-
188
- /*
189
- * Return an iterator to the next hashmap entry. Returns NULL if there are
190
- * no more entries.
191
- */
192
- struct hashmap_iter *hashmap_iter_next(const struct hashmap *map,
193
- const struct hashmap_iter *iter);
194
-
195
- /*
196
- * Remove the hashmap entry pointed to by this iterator and returns an
197
- * iterator to the next entry. Returns NULL if there are no more entries.
198
- */
199
- struct hashmap_iter *hashmap_iter_remove(struct hashmap *map,
200
- const struct hashmap_iter *iter);
201
-
202
- /*
203
- * Return the key of the entry pointed to by the iterator.
204
- */
205
- const void *hashmap_iter_get_key(const struct hashmap_iter *iter);
206
-
207
- /*
208
- * Return the data of the entry pointed to by the iterator.
209
- */
210
- void *hashmap_iter_get_data(const struct hashmap_iter *iter);
211
-
212
- /*
213
- * Set the data pointer of the entry pointed to by the iterator.
214
- */
215
- void hashmap_iter_set_data(const struct hashmap_iter *iter, void *data);
216
-
217
- /*
218
- * Invoke func for each entry in the hashmap. Unlike the hashmap_iter_*()
219
- * interface, this function supports calls to hashmap_remove() during iteration.
220
- * However, it is an error to put or remove an entry other than the current one,
221
- * and doing so will immediately halt iteration and return an error.
222
- * Iteration is stopped if func returns non-zero. Returns func's return
223
- * value if it is < 0, otherwise, 0.
224
- */
225
- int hashmap_foreach(const struct hashmap *map,
226
- int (*func)(const void *, void *, void *), void *arg);
227
-
228
- /*
229
- * Default hash function for string keys.
230
- * This is an implementation of the well-documented Jenkins one-at-a-time
231
- * hash function.
232
- */
233
- size_t hashmap_hash_string(const void *key);
234
-
235
- /*
236
- * Default key comparator function for string keys.
237
- */
238
- int hashmap_compare_string(const void *a, const void *b);
239
-
240
- /*
241
- * Default key allocation function for string keys. Use free() for the
242
- * key_free_func.
243
- */
244
- void *hashmap_alloc_key_string(const void *key);
245
-
246
-
247
- #ifdef HASHMAP_METRICS
248
- /*
249
- * Return the load factor.
250
- */
251
- double hashmap_load_factor(const struct hashmap *map);
252
-
253
- /*
254
- * Return the average number of collisions per entry.
255
- */
256
- double hashmap_collisions_mean(const struct hashmap *map);
257
-
258
- /*
259
- * Return the variance between entry collisions. The higher the variance,
260
- * the more likely the hash function is poor and is resulting in clustering.
261
- */
262
- double hashmap_collisions_variance(const struct hashmap *map);
263
- #endif
264
-
265
-
266
- #endif /* __HASHMAP_H__ */