localmemcache 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/example/hello.c +1 -1
- data/site/doc/classes/LocalMemCache.html +19 -350
- data/site/doc/classes/LocalMemCache.src/M000001.html +1 -1
- data/site/doc/classes/LocalMemCache/SharedObjectStorage.html +20 -20
- data/site/doc/classes/LocalMemCache/SharedObjectStorage.src/M000015.html +1 -1
- data/site/doc/classes/LocalMemCache/SharedObjectStorage.src/M000016.html +1 -1
- data/site/doc/classes/LocalMemCache/SharedObjectStorage.src/M000017.html +1 -1
- data/site/doc/classes/LocalMemCache/SharedObjectStorage.src/M000018.html +1 -1
- data/site/doc/created.rid +1 -1
- data/site/doc/files/extconf_rb.html +1 -1
- data/site/doc/files/localmemcache_rb.html +1 -1
- data/site/doc/files/rblocalmemcache_c.html +1 -1
- data/site/doc/fr_file_index.html +0 -2
- data/site/doc/fr_method_index.html +4 -17
- data/site/index.html +19 -3
- data/src/lmc_common.h +1 -1
- data/src/lmc_valloc.c +27 -1
- data/src/lmc_valloc.h +3 -1
- data/src/localmemcache.c +8 -5
- data/src/localmemcache.h +12 -3
- data/src/ruby-binding/localmemcache.rb +12 -0
- data/src/ruby-binding/rblocalmemcache.c +4 -1
- data/src/tests/bench-append +11 -0
- data/src/tests/bench-append.rb +61 -0
- data/src/tests/lmc.rb +3 -3
- metadata +16 -5
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.2
|
data/example/hello.c
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
int main() {
|
5
5
|
lmc_error_t e;
|
6
|
-
local_memcache_t *lmc = local_memcache_create("viewcounters", 0, 0, &e);
|
6
|
+
local_memcache_t *lmc = local_memcache_create("viewcounters", 0, 0, 0, &e);
|
7
7
|
if (!lmc) {
|
8
8
|
fprintf(stderr, "Couldn't create localmemcache: %s\n", e.error_str);
|
9
9
|
return 1;
|
@@ -58,10 +58,6 @@
|
|
58
58
|
<a href="../files/localmemcache_rb.html">
|
59
59
|
localmemcache.rb
|
60
60
|
</a>
|
61
|
-
<br />
|
62
|
-
<a href="../files/rblocalmemcache_c.html">
|
63
|
-
rblocalmemcache.c
|
64
|
-
</a>
|
65
61
|
<br />
|
66
62
|
</td>
|
67
63
|
</tr>
|
@@ -82,63 +78,6 @@
|
|
82
78
|
|
83
79
|
<div id="contextContent">
|
84
80
|
|
85
|
-
<div id="description">
|
86
|
-
<p>
|
87
|
-
<tt><a href="LocalMemCache.html">LocalMemCache</a></tt> provides for a
|
88
|
-
Hashtable of strings in shared memory (via a memory mapped file), which
|
89
|
-
thus can be shared between processes on a computer. Here is an example of
|
90
|
-
its usage:
|
91
|
-
</p>
|
92
|
-
<pre>
|
93
|
-
$lm = LocalMemCache.new :namespace => "viewcounters"
|
94
|
-
$lm[:foo] = 1
|
95
|
-
$lm[:foo] # -> "1"
|
96
|
-
$lm.delete(:foo)
|
97
|
-
</pre>
|
98
|
-
<p>
|
99
|
-
<tt><a href="LocalMemCache.html">LocalMemCache</a></tt> can also be used as
|
100
|
-
a persistent key value database, just use the :filename instead of the
|
101
|
-
:namespace parameter.
|
102
|
-
</p>
|
103
|
-
<pre>
|
104
|
-
$lm = LocalMemCache.new :filename => "my-database.lmc"
|
105
|
-
$lm[:foo] = 1
|
106
|
-
$lm[:foo] # -> "1"
|
107
|
-
$lm.delete(:foo)
|
108
|
-
|
109
|
-
== Default sizes of memory pools
|
110
|
-
|
111
|
-
The default size for memory pools is 1024 (MB). It cannot be changed later,
|
112
|
-
so choose a size that will provide enough space for all your data. You
|
113
|
-
might consider setting this size to the maximum filesize of your
|
114
|
-
filesystem. Also note that while these memory pools may look large on your
|
115
|
-
disk, they really aren't, because with sparse files only those parts of the
|
116
|
-
file which contain non-null data actually use disk space.
|
117
|
-
|
118
|
-
== Automatic recovery from crashes
|
119
|
-
|
120
|
-
In case a process is terminated while accessing a memory pool, other
|
121
|
-
processes will wait for the lock up to 2 seconds, and will then try to
|
122
|
-
resume the aborted operation. This can also be done explicitly by using
|
123
|
-
LocalMemCache.check(options).
|
124
|
-
|
125
|
-
== Clearing memory pools
|
126
|
-
|
127
|
-
Removing memory pools can be done with LocalMemCache.drop(options).
|
128
|
-
|
129
|
-
== Environment
|
130
|
-
|
131
|
-
If you use the :namespace parameter, the .lmc file for your namespace will
|
132
|
-
reside in /var/tmp/localmemcache. This can be overriden by setting the
|
133
|
-
LMC_NAMESPACES_ROOT_PATH variable in the environment.
|
134
|
-
|
135
|
-
== Storing Ruby Objects
|
136
|
-
|
137
|
-
If you want to store Ruby objects instead of just strings, consider
|
138
|
-
using LocalMemCache::SharedObjectStorage.
|
139
|
-
</pre>
|
140
|
-
|
141
|
-
</div>
|
142
81
|
|
143
82
|
|
144
83
|
</div>
|
@@ -147,20 +86,7 @@ a persistent key value database, just use the :filename instead of the
|
|
147
86
|
<h3 class="section-bar">Methods</h3>
|
148
87
|
|
149
88
|
<div class="name-list">
|
150
|
-
<a href="#M000005">[]</a>
|
151
|
-
<a href="#M000009">[]=</a>
|
152
|
-
<a href="#M000003">check</a>
|
153
|
-
<a href="#M000008">clear</a>
|
154
|
-
<a href="#M000013">close</a>
|
155
|
-
<a href="#M000006">delete</a>
|
156
|
-
<a href="#M000002">drop</a>
|
157
|
-
<a href="#M000011">each_pair</a>
|
158
|
-
<a href="#M000004">get</a>
|
159
|
-
<a href="#M000010">keys</a>
|
160
89
|
<a href="#M000001">new</a>
|
161
|
-
<a href="#M000012">random_pair</a>
|
162
|
-
<a href="#M000007">set</a>
|
163
|
-
<a href="#M000014">size</a>
|
164
90
|
</div>
|
165
91
|
</div>
|
166
92
|
|
@@ -201,73 +127,6 @@ Class <a href="LocalMemCache/ShmUnlockFailed.html" class="link">LocalMemCache::S
|
|
201
127
|
<div id="methods">
|
202
128
|
<h3 class="section-bar">Public Class methods</h3>
|
203
129
|
|
204
|
-
<div id="method-M000003" class="method-detail">
|
205
|
-
<a name="M000003"></a>
|
206
|
-
|
207
|
-
<div class="method-heading">
|
208
|
-
<a href="LocalMemCache.src/M000003.html" target="Code" class="method-signature"
|
209
|
-
onclick="popupCode('LocalMemCache.src/M000003.html');return false;">
|
210
|
-
<span class="method-name"> LocalMemCache.check(*args)<br />
|
211
|
-
</span>
|
212
|
-
</a>
|
213
|
-
</div>
|
214
|
-
|
215
|
-
<div class="method-description">
|
216
|
-
<p>
|
217
|
-
Tries to repair a corrupt namespace. Usually one doesn‘t call this
|
218
|
-
method directly, it‘s invoked automatically when operations time out.
|
219
|
-
</p>
|
220
|
-
<p>
|
221
|
-
valid options are [:namespace] [:filename]
|
222
|
-
</p>
|
223
|
-
<p>
|
224
|
-
The memory pool must be specified by either setting the :filename or
|
225
|
-
:namespace option.
|
226
|
-
</p>
|
227
|
-
</div>
|
228
|
-
</div>
|
229
|
-
|
230
|
-
<div id="method-M000002" class="method-detail">
|
231
|
-
<a name="M000002"></a>
|
232
|
-
|
233
|
-
<div class="method-heading">
|
234
|
-
<a href="LocalMemCache.src/M000002.html" target="Code" class="method-signature"
|
235
|
-
onclick="popupCode('LocalMemCache.src/M000002.html');return false;">
|
236
|
-
<span class="method-name"> LocalMemCache.drop(*args)<br />
|
237
|
-
</span>
|
238
|
-
</a>
|
239
|
-
</div>
|
240
|
-
|
241
|
-
<div class="method-description">
|
242
|
-
<p>
|
243
|
-
Deletes a memory pool. If the :force option is <a
|
244
|
-
href="LocalMemCache.html#M000007">set</a>, locked semaphores are removed as
|
245
|
-
well.
|
246
|
-
</p>
|
247
|
-
<p>
|
248
|
-
WARNING: Do only call this method with the :force option if you are sure
|
249
|
-
that you really want to remove this memory pool and no more processes are
|
250
|
-
still using it.
|
251
|
-
</p>
|
252
|
-
<p>
|
253
|
-
If you <a href="LocalMemCache.html#M000006">delete</a> a pool and other
|
254
|
-
processes still have handles open on it, the status of these handles
|
255
|
-
becomes undefined. There‘s no way for a process to know when a handle
|
256
|
-
is not valid anymore, so only <a
|
257
|
-
href="LocalMemCache.html#M000006">delete</a> a memory pool if you are sure
|
258
|
-
that all handles are closed.
|
259
|
-
</p>
|
260
|
-
<p>
|
261
|
-
valid options for <a href="LocalMemCache.html#M000002">drop</a> are
|
262
|
-
[:namespace] [:filename] [:force]
|
263
|
-
</p>
|
264
|
-
<p>
|
265
|
-
The memory pool must be specified by either setting the :filename or
|
266
|
-
:namespace option. The default for :force is false.
|
267
|
-
</p>
|
268
|
-
</div>
|
269
|
-
</div>
|
270
|
-
|
271
130
|
<div id="method-M000001" class="method-detail">
|
272
131
|
<a name="M000001"></a>
|
273
132
|
|
@@ -289,13 +148,28 @@ a shared memory region.
|
|
289
148
|
</p>
|
290
149
|
<p>
|
291
150
|
<a href="LocalMemCache.html#M000001">LocalMemCache.new</a>
|
151
|
+
:namespace=>"foo", :size_mb=> 1, :min_alloc_size => 256
|
152
|
+
</p>
|
153
|
+
<p>
|
154
|
+
<a href="LocalMemCache.html#M000001">LocalMemCache.new</a>
|
292
155
|
:filename=>"./foo.lmc"
|
293
156
|
</p>
|
294
157
|
<p>
|
158
|
+
<a href="LocalMemCache.html#M000001">LocalMemCache.new</a>
|
159
|
+
:filename=>"./foo.lmc", :min_alloc_size => 512
|
160
|
+
</p>
|
161
|
+
<p>
|
295
162
|
You must supply at least a :namespace or :filename parameter The size_mb
|
296
163
|
defaults to 1024 (1 GB).
|
297
164
|
</p>
|
298
165
|
<p>
|
166
|
+
The :min_alloc_size parameter was introduced to help with use cases that
|
167
|
+
intend to use a hash table with growing values. This is currently not
|
168
|
+
handled well by the internal allocator as it will end up with a large list
|
169
|
+
of unusable free blocks. By setting the :min_alloc_size parameter you help
|
170
|
+
the allocator to plan better ahead.
|
171
|
+
</p>
|
172
|
+
<p>
|
299
173
|
If you use the :namespace parameter, the .lmc file for your namespace will
|
300
174
|
reside in /var/tmp/localmemcache. This can be overriden by setting the
|
301
175
|
LMC_NAMESPACES_ROOT_PATH variable in the environment.
|
@@ -304,215 +178,10 @@ LMC_NAMESPACES_ROOT_PATH variable in the environment.
|
|
304
178
|
When you first call .<a href="LocalMemCache.html#M000001">new</a> for a
|
305
179
|
previously not existing memory pool, a sparse file will be created and
|
306
180
|
memory and disk space will be allocated to hold the empty hashtable (about
|
307
|
-
100K), so the size_mb refers only to the maximum
|
308
|
-
href="LocalMemCache.html#
|
309
|
-
|
310
|
-
|
311
|
-
address space of your process.
|
312
|
-
</p>
|
313
|
-
</div>
|
314
|
-
</div>
|
315
|
-
|
316
|
-
<h3 class="section-bar">Public Instance methods</h3>
|
317
|
-
|
318
|
-
<div id="method-M000005" class="method-detail">
|
319
|
-
<a name="M000005"></a>
|
320
|
-
|
321
|
-
<div class="method-heading">
|
322
|
-
<a href="LocalMemCache.src/M000005.html" target="Code" class="method-signature"
|
323
|
-
onclick="popupCode('LocalMemCache.src/M000005.html');return false;">
|
324
|
-
<span class="method-name">lmc.get(key) → string value or nil<br />
|
325
|
-
lmc[key] → string value or nil<br />
|
326
|
-
</span>
|
327
|
-
</a>
|
328
|
-
</div>
|
329
|
-
|
330
|
-
<div class="method-description">
|
331
|
-
<p>
|
332
|
-
Retrieve string value from hashtable.
|
333
|
-
</p>
|
334
|
-
</div>
|
335
|
-
</div>
|
336
|
-
|
337
|
-
<div id="method-M000009" class="method-detail">
|
338
|
-
<a name="M000009"></a>
|
339
|
-
|
340
|
-
<div class="method-heading">
|
341
|
-
<a href="LocalMemCache.src/M000009.html" target="Code" class="method-signature"
|
342
|
-
onclick="popupCode('LocalMemCache.src/M000009.html');return false;">
|
343
|
-
<span class="method-name">lmc.set(key, value) → Qnil<br />
|
344
|
-
lmc[key]=value → Qnil<br />
|
345
|
-
</span>
|
346
|
-
</a>
|
347
|
-
</div>
|
348
|
-
|
349
|
-
<div class="method-description">
|
350
|
-
<p>
|
351
|
-
Set value for key in hashtable. Value and key will be converted to string.
|
352
|
-
</p>
|
353
|
-
</div>
|
354
|
-
</div>
|
355
|
-
|
356
|
-
<div id="method-M000008" class="method-detail">
|
357
|
-
<a name="M000008"></a>
|
358
|
-
|
359
|
-
<div class="method-heading">
|
360
|
-
<a href="LocalMemCache.src/M000008.html" target="Code" class="method-signature"
|
361
|
-
onclick="popupCode('LocalMemCache.src/M000008.html');return false;">
|
362
|
-
<span class="method-name">lmc.clear → Qnil<br />
|
363
|
-
</span>
|
364
|
-
</a>
|
365
|
-
</div>
|
366
|
-
|
367
|
-
<div class="method-description">
|
368
|
-
<p>
|
369
|
-
Clears content of hashtable.
|
370
|
-
</p>
|
371
|
-
</div>
|
372
|
-
</div>
|
373
|
-
|
374
|
-
<div id="method-M000013" class="method-detail">
|
375
|
-
<a name="M000013"></a>
|
376
|
-
|
377
|
-
<div class="method-heading">
|
378
|
-
<a href="LocalMemCache.src/M000013.html" target="Code" class="method-signature"
|
379
|
-
onclick="popupCode('LocalMemCache.src/M000013.html');return false;">
|
380
|
-
<span class="method-name">lmc.close() → Qnil<br />
|
381
|
-
</span>
|
382
|
-
</a>
|
383
|
-
</div>
|
384
|
-
|
385
|
-
<div class="method-description">
|
386
|
-
<p>
|
387
|
-
Releases hashtable.
|
388
|
-
</p>
|
389
|
-
</div>
|
390
|
-
</div>
|
391
|
-
|
392
|
-
<div id="method-M000006" class="method-detail">
|
393
|
-
<a name="M000006"></a>
|
394
|
-
|
395
|
-
<div class="method-heading">
|
396
|
-
<a href="LocalMemCache.src/M000006.html" target="Code" class="method-signature"
|
397
|
-
onclick="popupCode('LocalMemCache.src/M000006.html');return false;">
|
398
|
-
<span class="method-name">lmc.delete(key) → Qnil<br />
|
399
|
-
</span>
|
400
|
-
</a>
|
401
|
-
</div>
|
402
|
-
|
403
|
-
<div class="method-description">
|
404
|
-
<p>
|
405
|
-
Deletes key from hashtable. The key is converted to string.
|
406
|
-
</p>
|
407
|
-
</div>
|
408
|
-
</div>
|
409
|
-
|
410
|
-
<div id="method-M000011" class="method-detail">
|
411
|
-
<a name="M000011"></a>
|
412
|
-
|
413
|
-
<div class="method-heading">
|
414
|
-
<a href="LocalMemCache.src/M000011.html" target="Code" class="method-signature"
|
415
|
-
onclick="popupCode('LocalMemCache.src/M000011.html');return false;">
|
416
|
-
<span class="method-name">lmc.each_pair {|k, v| block } → nil<br />
|
417
|
-
</span>
|
418
|
-
</a>
|
419
|
-
</div>
|
420
|
-
|
421
|
-
<div class="method-description">
|
422
|
-
<p>
|
423
|
-
Iterates over hashtable.
|
424
|
-
</p>
|
425
|
-
</div>
|
426
|
-
</div>
|
427
|
-
|
428
|
-
<div id="method-M000004" class="method-detail">
|
429
|
-
<a name="M000004"></a>
|
430
|
-
|
431
|
-
<div class="method-heading">
|
432
|
-
<a href="LocalMemCache.src/M000004.html" target="Code" class="method-signature"
|
433
|
-
onclick="popupCode('LocalMemCache.src/M000004.html');return false;">
|
434
|
-
<span class="method-name">lmc.get(key) → string value or nil<br />
|
435
|
-
lmc[key] → string value or nil<br />
|
436
|
-
</span>
|
437
|
-
</a>
|
438
|
-
</div>
|
439
|
-
|
440
|
-
<div class="method-description">
|
441
|
-
<p>
|
442
|
-
Retrieve string value from hashtable.
|
443
|
-
</p>
|
444
|
-
</div>
|
445
|
-
</div>
|
446
|
-
|
447
|
-
<div id="method-M000010" class="method-detail">
|
448
|
-
<a name="M000010"></a>
|
449
|
-
|
450
|
-
<div class="method-heading">
|
451
|
-
<a href="LocalMemCache.src/M000010.html" target="Code" class="method-signature"
|
452
|
-
onclick="popupCode('LocalMemCache.src/M000010.html');return false;">
|
453
|
-
<span class="method-name">lmc.keys() → array or nil<br />
|
454
|
-
</span>
|
455
|
-
</a>
|
456
|
-
</div>
|
457
|
-
|
458
|
-
<div class="method-description">
|
459
|
-
<p>
|
460
|
-
Returns a list of <a href="LocalMemCache.html#M000010">keys</a>.
|
461
|
-
</p>
|
462
|
-
</div>
|
463
|
-
</div>
|
464
|
-
|
465
|
-
<div id="method-M000012" class="method-detail">
|
466
|
-
<a name="M000012"></a>
|
467
|
-
|
468
|
-
<div class="method-heading">
|
469
|
-
<a href="LocalMemCache.src/M000012.html" target="Code" class="method-signature"
|
470
|
-
onclick="popupCode('LocalMemCache.src/M000012.html');return false;">
|
471
|
-
<span class="method-name">lmc.random_pair() → [key, value] or nil<br />
|
472
|
-
</span>
|
473
|
-
</a>
|
474
|
-
</div>
|
475
|
-
|
476
|
-
<div class="method-description">
|
477
|
-
<p>
|
478
|
-
Retrieves random pair from hashtable.
|
479
|
-
</p>
|
480
|
-
</div>
|
481
|
-
</div>
|
482
|
-
|
483
|
-
<div id="method-M000007" class="method-detail">
|
484
|
-
<a name="M000007"></a>
|
485
|
-
|
486
|
-
<div class="method-heading">
|
487
|
-
<a href="LocalMemCache.src/M000007.html" target="Code" class="method-signature"
|
488
|
-
onclick="popupCode('LocalMemCache.src/M000007.html');return false;">
|
489
|
-
<span class="method-name">lmc.set(key, value) → Qnil<br />
|
490
|
-
lmc[key]=value → Qnil<br />
|
491
|
-
</span>
|
492
|
-
</a>
|
493
|
-
</div>
|
494
|
-
|
495
|
-
<div class="method-description">
|
496
|
-
<p>
|
497
|
-
Set value for key in hashtable. Value and key will be converted to string.
|
498
|
-
</p>
|
499
|
-
</div>
|
500
|
-
</div>
|
501
|
-
|
502
|
-
<div id="method-M000014" class="method-detail">
|
503
|
-
<a name="M000014"></a>
|
504
|
-
|
505
|
-
<div class="method-heading">
|
506
|
-
<a href="LocalMemCache.src/M000014.html" target="Code" class="method-signature"
|
507
|
-
onclick="popupCode('LocalMemCache.src/M000014.html');return false;">
|
508
|
-
<span class="method-name">lmc.size → number<br />
|
509
|
-
</span>
|
510
|
-
</a>
|
511
|
-
</div>
|
512
|
-
|
513
|
-
<div class="method-description">
|
514
|
-
<p>
|
515
|
-
Number of pairs in the hashtable.
|
181
|
+
100K), so the size_mb refers only to the maximum size of the memory pool.
|
182
|
+
.<a href="LocalMemCache.html#M000001">new</a> for an already existing
|
183
|
+
memory pool will only map the already previously allocated RAM into the
|
184
|
+
virtual address space of your process.
|
516
185
|
</p>
|
517
186
|
</div>
|
518
187
|
</div>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
11
11
|
</head>
|
12
12
|
<body class="standalone-code">
|
13
|
-
<pre><span class="ruby-comment cmt"># File localmemcache.rb, line
|
13
|
+
<pre><span class="ruby-comment cmt"># File localmemcache.rb, line 52</span>
|
14
14
|
<span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">options</span>)
|
15
15
|
<span class="ruby-identifier">o</span> = { <span class="ruby-identifier">:size_mb</span> =<span class="ruby-operator">></span> <span class="ruby-value">0</span> }.<span class="ruby-identifier">update</span>(<span class="ruby-identifier">options</span> <span class="ruby-operator">||</span> {})
|
16
16
|
<span class="ruby-identifier">_new</span>(<span class="ruby-identifier">o</span>);
|
@@ -97,10 +97,10 @@ strings for the keys, though).
|
|
97
97
|
<h3 class="section-bar">Methods</h3>
|
98
98
|
|
99
99
|
<div class="name-list">
|
100
|
-
<a href="#
|
101
|
-
<a href="#
|
102
|
-
<a href="#
|
103
|
-
<a href="#
|
100
|
+
<a href="#M000003">[]</a>
|
101
|
+
<a href="#M000002">[]=</a>
|
102
|
+
<a href="#M000004">each_pair</a>
|
103
|
+
<a href="#M000005">random_pair</a>
|
104
104
|
</div>
|
105
105
|
</div>
|
106
106
|
|
@@ -122,12 +122,12 @@ strings for the keys, though).
|
|
122
122
|
<div id="methods">
|
123
123
|
<h3 class="section-bar">Public Instance methods</h3>
|
124
124
|
|
125
|
-
<div id="method-
|
126
|
-
<a name="
|
125
|
+
<div id="method-M000003" class="method-detail">
|
126
|
+
<a name="M000003"></a>
|
127
127
|
|
128
128
|
<div class="method-heading">
|
129
|
-
<a href="SharedObjectStorage.src/
|
130
|
-
onclick="popupCode('SharedObjectStorage.src/
|
129
|
+
<a href="SharedObjectStorage.src/M000003.html" target="Code" class="method-signature"
|
130
|
+
onclick="popupCode('SharedObjectStorage.src/M000003.html');return false;">
|
131
131
|
<span class="method-name">[]</span><span class="method-args">(key)</span>
|
132
132
|
</a>
|
133
133
|
</div>
|
@@ -136,12 +136,12 @@ strings for the keys, though).
|
|
136
136
|
</div>
|
137
137
|
</div>
|
138
138
|
|
139
|
-
<div id="method-
|
140
|
-
<a name="
|
139
|
+
<div id="method-M000002" class="method-detail">
|
140
|
+
<a name="M000002"></a>
|
141
141
|
|
142
142
|
<div class="method-heading">
|
143
|
-
<a href="SharedObjectStorage.src/
|
144
|
-
onclick="popupCode('SharedObjectStorage.src/
|
143
|
+
<a href="SharedObjectStorage.src/M000002.html" target="Code" class="method-signature"
|
144
|
+
onclick="popupCode('SharedObjectStorage.src/M000002.html');return false;">
|
145
145
|
<span class="method-name">[]=</span><span class="method-args">(key,val)</span>
|
146
146
|
</a>
|
147
147
|
</div>
|
@@ -150,12 +150,12 @@ strings for the keys, though).
|
|
150
150
|
</div>
|
151
151
|
</div>
|
152
152
|
|
153
|
-
<div id="method-
|
154
|
-
<a name="
|
153
|
+
<div id="method-M000004" class="method-detail">
|
154
|
+
<a name="M000004"></a>
|
155
155
|
|
156
156
|
<div class="method-heading">
|
157
|
-
<a href="SharedObjectStorage.src/
|
158
|
-
onclick="popupCode('SharedObjectStorage.src/
|
157
|
+
<a href="SharedObjectStorage.src/M000004.html" target="Code" class="method-signature"
|
158
|
+
onclick="popupCode('SharedObjectStorage.src/M000004.html');return false;">
|
159
159
|
<span class="method-name">each_pair</span><span class="method-args">(&block)</span>
|
160
160
|
</a>
|
161
161
|
</div>
|
@@ -164,12 +164,12 @@ strings for the keys, though).
|
|
164
164
|
</div>
|
165
165
|
</div>
|
166
166
|
|
167
|
-
<div id="method-
|
168
|
-
<a name="
|
167
|
+
<div id="method-M000005" class="method-detail">
|
168
|
+
<a name="M000005"></a>
|
169
169
|
|
170
170
|
<div class="method-heading">
|
171
|
-
<a href="SharedObjectStorage.src/
|
172
|
-
onclick="popupCode('SharedObjectStorage.src/
|
171
|
+
<a href="SharedObjectStorage.src/M000005.html" target="Code" class="method-signature"
|
172
|
+
onclick="popupCode('SharedObjectStorage.src/M000005.html');return false;">
|
173
173
|
<span class="method-name">random_pair</span><span class="method-args">()</span>
|
174
174
|
</a>
|
175
175
|
</div>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
|
11
11
|
</head>
|
12
12
|
<body class="standalone-code">
|
13
|
-
<pre><span class="ruby-comment cmt"># File localmemcache.rb, line
|
13
|
+
<pre><span class="ruby-comment cmt"># File localmemcache.rb, line 57</span>
|
14
14
|
<span class="ruby-keyword kw">def</span> <span class="ruby-operator">[]=</span>(<span class="ruby-identifier">key</span>,<span class="ruby-identifier">val</span>) <span class="ruby-keyword kw">super</span>(<span class="ruby-identifier">key</span>, <span class="ruby-constant">Marshal</span>.<span class="ruby-identifier">dump</span>(<span class="ruby-identifier">val</span>)) <span class="ruby-keyword kw">end</span></pre>
|
15
15
|
</body>
|
16
16
|
</html>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
|
11
11
|
</head>
|
12
12
|
<body class="standalone-code">
|
13
|
-
<pre><span class="ruby-comment cmt"># File localmemcache.rb, line
|
13
|
+
<pre><span class="ruby-comment cmt"># File localmemcache.rb, line 58</span>
|
14
14
|
<span class="ruby-keyword kw">def</span> <span class="ruby-operator">[]</span>(<span class="ruby-identifier">key</span>) <span class="ruby-identifier">v</span> = <span class="ruby-keyword kw">super</span>(<span class="ruby-identifier">key</span>); <span class="ruby-identifier">v</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-value">? </span><span class="ruby-keyword kw">nil</span> <span class="ruby-operator">:</span> <span class="ruby-constant">Marshal</span>.<span class="ruby-identifier">load</span>(<span class="ruby-identifier">v</span>) <span class="ruby-keyword kw">end</span></pre>
|
15
15
|
</body>
|
16
16
|
</html>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
|
11
11
|
</head>
|
12
12
|
<body class="standalone-code">
|
13
|
-
<pre><span class="ruby-comment cmt"># File localmemcache.rb, line
|
13
|
+
<pre><span class="ruby-comment cmt"># File localmemcache.rb, line 59</span>
|
14
14
|
<span class="ruby-keyword kw">def</span> <span class="ruby-identifier">each_pair</span>(<span class="ruby-operator">&</span><span class="ruby-identifier">block</span>)
|
15
15
|
<span class="ruby-keyword kw">super</span> {<span class="ruby-operator">|</span><span class="ruby-identifier">k</span>, <span class="ruby-identifier">mv</span><span class="ruby-operator">|</span> <span class="ruby-identifier">block</span>.<span class="ruby-identifier">call</span>(<span class="ruby-identifier">k</span>, <span class="ruby-constant">Marshal</span>.<span class="ruby-identifier">load</span>(<span class="ruby-identifier">mv</span>)) }
|
16
16
|
<span class="ruby-keyword kw">end</span></pre>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
|
11
11
|
</head>
|
12
12
|
<body class="standalone-code">
|
13
|
-
<pre><span class="ruby-comment cmt"># File localmemcache.rb, line
|
13
|
+
<pre><span class="ruby-comment cmt"># File localmemcache.rb, line 62</span>
|
14
14
|
<span class="ruby-keyword kw">def</span> <span class="ruby-identifier">random_pair</span>
|
15
15
|
<span class="ruby-identifier">rp</span> = <span class="ruby-keyword kw">super</span>
|
16
16
|
<span class="ruby-identifier">rp</span>.<span class="ruby-identifier">nil?</span> <span class="ruby-value">? </span><span class="ruby-keyword kw">nil</span> <span class="ruby-operator">:</span> [<span class="ruby-identifier">rp</span>.<span class="ruby-identifier">first</span>, <span class="ruby-constant">Marshal</span>.<span class="ruby-identifier">load</span>(<span class="ruby-identifier">rp</span>.<span class="ruby-identifier">last</span>)]
|
data/site/doc/created.rid
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
Mon, 10 Aug 2009 14:36:31 +0000
|
data/site/doc/fr_file_index.html
CHANGED
@@ -20,9 +20,7 @@
|
|
20
20
|
<div id="index">
|
21
21
|
<h1 class="section-bar">Files</h1>
|
22
22
|
<div id="index-entries">
|
23
|
-
<a href="files/extconf_rb.html">extconf.rb</a><br />
|
24
23
|
<a href="files/localmemcache_rb.html">localmemcache.rb</a><br />
|
25
|
-
<a href="files/rblocalmemcache_c.html">rblocalmemcache.c</a><br />
|
26
24
|
</div>
|
27
25
|
</div>
|
28
26
|
</body>
|
@@ -20,24 +20,11 @@
|
|
20
20
|
<div id="index">
|
21
21
|
<h1 class="section-bar">Methods</h1>
|
22
22
|
<div id="index-entries">
|
23
|
-
<a href="classes/LocalMemCache/SharedObjectStorage.html#
|
24
|
-
<a href="classes/LocalMemCache.html#
|
25
|
-
<a href="classes/LocalMemCache.html#
|
26
|
-
<a href="classes/LocalMemCache/SharedObjectStorage.html#M000015">[]= (LocalMemCache::SharedObjectStorage)</a><br />
|
27
|
-
<a href="classes/LocalMemCache.html#M000003">check (LocalMemCache)</a><br />
|
28
|
-
<a href="classes/LocalMemCache.html#M000008">clear (LocalMemCache)</a><br />
|
29
|
-
<a href="classes/LocalMemCache.html#M000013">close (LocalMemCache)</a><br />
|
30
|
-
<a href="classes/LocalMemCache.html#M000006">delete (LocalMemCache)</a><br />
|
31
|
-
<a href="classes/LocalMemCache.html#M000002">drop (LocalMemCache)</a><br />
|
32
|
-
<a href="classes/LocalMemCache.html#M000011">each_pair (LocalMemCache)</a><br />
|
33
|
-
<a href="classes/LocalMemCache/SharedObjectStorage.html#M000017">each_pair (LocalMemCache::SharedObjectStorage)</a><br />
|
34
|
-
<a href="classes/LocalMemCache.html#M000004">get (LocalMemCache)</a><br />
|
35
|
-
<a href="classes/LocalMemCache.html#M000010">keys (LocalMemCache)</a><br />
|
23
|
+
<a href="classes/LocalMemCache/SharedObjectStorage.html#M000003">[] (LocalMemCache::SharedObjectStorage)</a><br />
|
24
|
+
<a href="classes/LocalMemCache/SharedObjectStorage.html#M000002">[]= (LocalMemCache::SharedObjectStorage)</a><br />
|
25
|
+
<a href="classes/LocalMemCache/SharedObjectStorage.html#M000004">each_pair (LocalMemCache::SharedObjectStorage)</a><br />
|
36
26
|
<a href="classes/LocalMemCache.html#M000001">new (LocalMemCache)</a><br />
|
37
|
-
<a href="classes/LocalMemCache.html#
|
38
|
-
<a href="classes/LocalMemCache/SharedObjectStorage.html#M000018">random_pair (LocalMemCache::SharedObjectStorage)</a><br />
|
39
|
-
<a href="classes/LocalMemCache.html#M000007">set (LocalMemCache)</a><br />
|
40
|
-
<a href="classes/LocalMemCache.html#M000014">size (LocalMemCache)</a><br />
|
27
|
+
<a href="classes/LocalMemCache/SharedObjectStorage.html#M000005">random_pair (LocalMemCache::SharedObjectStorage)</a><br />
|
41
28
|
</div>
|
42
29
|
</div>
|
43
30
|
</body>
|
data/site/index.html
CHANGED
@@ -17,6 +17,16 @@ speed</b>.
|
|
17
17
|
Since version 0.3.0 it supports <b>persistence</b>, also making it <b>a fast
|
18
18
|
alternative to GDBM, Berkeley DB, and Tokyo Cabinet</b>.
|
19
19
|
|
20
|
+
<h2>Version 0.4.2: Improving Append Performance (2009-08-10)</h2>
|
21
|
+
|
22
|
+
In 0.4.2 the <b>:min_alloc_size</b> parameter was introduced to help with use
|
23
|
+
cases that intend to use a hash table with growing values. This is
|
24
|
+
currently not handled well by the internal allocator as it will end up
|
25
|
+
with a large list of unusable free blocks. By setting the
|
26
|
+
<b>:min_alloc_size</b> parameter you help the allocator to plan better
|
27
|
+
ahead. (<a href="http://localmemcache.rubyforge.org/doc/classes/LocalMemCache.html#M000001">more</a>)
|
28
|
+
|
29
|
+
|
20
30
|
<h2>Key features as of 0.4.0 (2009-05-16)</h2>
|
21
31
|
<li><a href="#performance">blazingly fast</a></li>
|
22
32
|
<li>a very simple API</li>
|
@@ -45,7 +55,7 @@ sometimes hangs there, it is not yet clear what the problem is.
|
|
45
55
|
If you just want to use the <b>C API</b>, download the .tar.gz from <a href="http://rubyforge.org/frs/?group_id=7925">here</a>.
|
46
56
|
|
47
57
|
<h2>Using</h2>
|
48
|
-
<b>API</b>: <a href="http://github.com/sck/localmemcache/blob/
|
58
|
+
<b>API</b>: <a href="http://github.com/sck/localmemcache/blob/d72a5bd825b0fb573f1048ea9cae92d8c143525c/src/localmemcache.h">C</a>|<a href="http://localmemcache.rubyforge.org/doc/">Ruby</a><br>
|
49
59
|
<p><pre><code>require 'localmemcache'
|
50
60
|
# 1. the memcached way
|
51
61
|
# $lm = LocalMemCache.new :namespace => :viewcounters
|
@@ -59,7 +69,7 @@ $lm[:foo]
|
|
59
69
|
$lm.delete(:foo)
|
60
70
|
|
61
71
|
</code></pre>
|
62
|
-
(C version of this example: <a href="http://github.com/sck/localmemcache/blob/
|
72
|
+
(C version of this example: <a href="http://github.com/sck/localmemcache/blob/d72a5bd825b0fb573f1048ea9cae92d8c143525c/example/hello.c">hello.c</a>)
|
63
73
|
</p>
|
64
74
|
|
65
75
|
<a name="performance" id="performance"></a>
|
@@ -99,7 +109,13 @@ can be retrieved by executing</p>
|
|
99
109
|
<pre><code>git clone git://github.com/sck/localmemcache.git
|
100
110
|
</code></pre>
|
101
111
|
|
102
|
-
<h2>
|
112
|
+
<h2>Who uses Localmemcache?</h2>
|
113
|
+
|
114
|
+
<a href="http://www.personifi.com">Personifi</a> use Localmemcache to
|
115
|
+
serve billions of hits each month. Armin Roehrl: "we use
|
116
|
+
localmemcache because it solves one problem very well and we love it!"
|
117
|
+
|
118
|
+
<h2>Tips for backups</h2>
|
103
119
|
|
104
120
|
Note that you cannot copy Localmemcache's .lmc files while other
|
105
121
|
processes are making changes to the data, this will likely result in a
|
data/src/lmc_common.h
CHANGED
data/src/lmc_valloc.c
CHANGED
@@ -52,6 +52,32 @@ void lmc_dump(void *base) {
|
|
52
52
|
}
|
53
53
|
}
|
54
54
|
|
55
|
+
size_t lmc_min_alloc_size(void *base) {
|
56
|
+
lmc_mem_descriptor_t *md = base;
|
57
|
+
return md->version > 1 ? md->min_alloc_size : 0;
|
58
|
+
}
|
59
|
+
|
60
|
+
/*
|
61
|
+
* Thanks to: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
|
62
|
+
*/
|
63
|
+
size_t round_to_next_power_of_2(size_t v) {
|
64
|
+
v--;
|
65
|
+
v |= v >> 1;
|
66
|
+
v |= v >> 2;
|
67
|
+
v |= v >> 4;
|
68
|
+
v |= v >> 8;
|
69
|
+
v |= v >> 16;
|
70
|
+
//v |= v >> 32;
|
71
|
+
v++;
|
72
|
+
return v;
|
73
|
+
}
|
74
|
+
|
75
|
+
void lmc_set_min_alloc_size(void *base, size_t s) {
|
76
|
+
lmc_mem_descriptor_t *md = base;
|
77
|
+
if (md->version < 2) { return; }
|
78
|
+
md->min_alloc_size = round_to_next_power_of_2(s);
|
79
|
+
}
|
80
|
+
|
55
81
|
int lmc_is_va_valid(void *base, size_t va) {
|
56
82
|
lmc_mem_descriptor_t *md = base;
|
57
83
|
lmc_mem_chunk_descriptor_t* c = base + va;
|
@@ -140,9 +166,9 @@ size_t __s(char *where, lmc_mem_status_t ms, size_t mem_before, size_t expected_
|
|
140
166
|
|
141
167
|
size_t lmc_valloc(void *base, size_t size) {
|
142
168
|
lmc_mem_descriptor_t *md = base;
|
143
|
-
// consider: make size divisible by power of 2
|
144
169
|
size_t s = lmc_max(size + sizeof(size_t),
|
145
170
|
sizeof(lmc_mem_chunk_descriptor_t) + sizeof(size_t));
|
171
|
+
s = lmc_max(lmc_min_alloc_size(base), round_to_next_power_of_2(s));
|
146
172
|
lmc_mem_chunk_descriptor_t *c = md_first_free(base);
|
147
173
|
lmc_mem_chunk_descriptor_t *p = NULL;
|
148
174
|
if (size == 0) { return 0; }
|
data/src/lmc_valloc.h
CHANGED
@@ -21,13 +21,14 @@ typedef struct {
|
|
21
21
|
|
22
22
|
typedef struct {
|
23
23
|
size_t first_free;
|
24
|
-
size_t dummy2;
|
24
|
+
size_t dummy2; // dummy for next
|
25
25
|
size_t total_size;
|
26
26
|
size_t magic;
|
27
27
|
size_t va_hash;
|
28
28
|
int locked;
|
29
29
|
size_t version;
|
30
30
|
lmc_log_descriptor_t log;
|
31
|
+
size_t min_alloc_size;
|
31
32
|
} lmc_mem_descriptor_t;
|
32
33
|
|
33
34
|
typedef struct {
|
@@ -49,5 +50,6 @@ int lmc_um_find_leaks(void *base, char *bf);
|
|
49
50
|
|
50
51
|
lmc_log_descriptor_t *lmc_log_op(void *base, int opid);
|
51
52
|
void lmc_log_finish(void *base);
|
53
|
+
void lmc_set_min_alloc_size(void *base, size_t s);
|
52
54
|
|
53
55
|
#endif
|
data/src/localmemcache.c
CHANGED
@@ -20,6 +20,7 @@ int lmc_set_lock_flag(void *base, lmc_error_t *e) {
|
|
20
20
|
return 1;
|
21
21
|
}
|
22
22
|
|
23
|
+
|
23
24
|
int lmc_release_lock_flag(void *base, lmc_error_t *e) {
|
24
25
|
lmc_mem_descriptor_t *md = base;
|
25
26
|
if (md->locked != 1) {
|
@@ -78,7 +79,7 @@ int local_memcache_drop_namespace(const char *namespace, const char *filename,
|
|
78
79
|
int __local_memcache_check_namespace(const char *clean_ns, lmc_error_t *e);
|
79
80
|
|
80
81
|
local_memcache_t *__local_memcache_create(const char *namespace, size_t size,
|
81
|
-
int force, int *ok, lmc_error_t* e) {
|
82
|
+
long min_alloc_size, int force, int *ok, lmc_error_t* e) {
|
82
83
|
int d;
|
83
84
|
if (!ok) { ok = &d; }
|
84
85
|
*ok = 1;
|
@@ -114,7 +115,7 @@ retry:
|
|
114
115
|
if (!force) goto release_and_fail;
|
115
116
|
*ok = 0;
|
116
117
|
}
|
117
|
-
if (lmc_get_db_version(lmc->base)
|
118
|
+
if (lmc_get_db_version(lmc->base) > LMC_DB_VERSION) {
|
118
119
|
lmc_handle_error_with_err_string("local_memcache_create",
|
119
120
|
"DB version is incompatible", "DBVersionNotSupported", e);
|
120
121
|
goto unlock_and_fail;
|
@@ -129,6 +130,7 @@ retry:
|
|
129
130
|
lmc->va_hash = md->va_hash;
|
130
131
|
}
|
131
132
|
if (*ok) {
|
133
|
+
lmc_set_min_alloc_size(lmc->base, min_alloc_size);
|
132
134
|
lmc_release_lock_flag(lmc->base, e);
|
133
135
|
lmc_lock_release("local_memcache_create", lmc->lock, e);
|
134
136
|
}
|
@@ -146,14 +148,15 @@ failed:
|
|
146
148
|
}
|
147
149
|
|
148
150
|
local_memcache_t *local_memcache_create(const char *namespace,
|
149
|
-
const char *filename, double size_mb,
|
151
|
+
const char *filename, double size_mb, size_t min_alloc_size,
|
152
|
+
lmc_error_t* e) {
|
150
153
|
char clean_ns[1024];
|
151
154
|
double s = size_mb == 0.0 ? 1024.0 : size_mb;
|
152
155
|
size_t si = s * 1024 * 1024;
|
153
156
|
//printf("size: %f, s: %f, si: %zd\n", size_mb, s, si);
|
154
157
|
if (!lmc_namespace_or_filename((char *)clean_ns, namespace, filename, e))
|
155
158
|
return 0;
|
156
|
-
return __local_memcache_create((char *)clean_ns, si, 0, 0, e);
|
159
|
+
return __local_memcache_create((char *)clean_ns, si, min_alloc_size, 0, 0, e);
|
157
160
|
}
|
158
161
|
|
159
162
|
int __local_memcache_check_namespace(const char *clean_ns, lmc_error_t *e) {
|
@@ -180,7 +183,7 @@ int __local_memcache_check_namespace(const char *clean_ns, lmc_error_t *e) {
|
|
180
183
|
size_t ns_size = lmc_namespace_size((char *)clean_ns);
|
181
184
|
int ok;
|
182
185
|
local_memcache_t *lmc = __local_memcache_create((char *)clean_ns, ns_size,
|
183
|
-
1, &ok, e);
|
186
|
+
0, 1, &ok, e);
|
184
187
|
if (!lmc) {
|
185
188
|
lmc_handle_error_with_err_string("__local_memcache_create",
|
186
189
|
"Unable to attach memory pool", "InitError", e);
|
data/src/localmemcache.h
CHANGED
@@ -95,14 +95,22 @@ typedef struct {
|
|
95
95
|
*
|
96
96
|
* lmc_error_t e;
|
97
97
|
* // open via namespace
|
98
|
-
* local_memcache_t *lmc = local_memcache_create("viewcounters", 0, 0, &e);
|
98
|
+
* local_memcache_t *lmc = local_memcache_create("viewcounters", 0, 0, 0, &e);
|
99
99
|
* // open via filename
|
100
|
-
* local_memcache_t *lmc = local_memcache_create(0, "./foo.lmc", 0, &e);
|
100
|
+
* local_memcache_t *lmc = local_memcache_create(0, "./foo.lmc", 0, 0, &e);
|
101
|
+
* // open via filename + min_alloc_size set
|
102
|
+
* local_memcache_t *lmc = local_memcache_create(0, "./foo.lmc", 0, 1024, &e);
|
101
103
|
*
|
102
104
|
* You must supply at least a namespace or filename parameter
|
103
105
|
*
|
104
106
|
* The size_mb defaults to 1024 (1 GB).
|
105
107
|
*
|
108
|
+
* The min_alloc_size parameter was introduced to help with use cases that
|
109
|
+
* intend to use a hash table with growing values. This is currently not
|
110
|
+
* handled well by the internal allocator as it will end up with a large list
|
111
|
+
* of unusable free blocks. By setting the min_alloc_size parameter you help
|
112
|
+
* the allocator to plan better ahead.
|
113
|
+
*
|
106
114
|
* If you use the namespace parameter, the .lmc file for your namespace will
|
107
115
|
* reside in /var/tmp/localmemcache. This can be overriden by setting the
|
108
116
|
* LMC_NAMESPACES_ROOT_PATH variable in the environment.
|
@@ -115,7 +123,8 @@ typedef struct {
|
|
115
123
|
* virtual address space of your process.
|
116
124
|
*/
|
117
125
|
local_memcache_t *local_memcache_create(const char *namespace,
|
118
|
-
const char *filename, double size_mb,
|
126
|
+
const char *filename, double size_mb, size_t min_alloc_size,
|
127
|
+
lmc_error_t* e);
|
119
128
|
|
120
129
|
/*
|
121
130
|
* Retrieve string value from hashtable.
|
@@ -19,12 +19,24 @@ class LocalMemCache
|
|
19
19
|
# Creates a new handle for accessing a shared memory region.
|
20
20
|
#
|
21
21
|
# LocalMemCache.new :namespace=>"foo", :size_mb=> 1
|
22
|
+
#
|
23
|
+
# LocalMemCache.new :namespace=>"foo", :size_mb=> 1, :min_alloc_size => 256
|
24
|
+
#
|
25
|
+
#
|
22
26
|
#
|
23
27
|
# LocalMemCache.new :filename=>"./foo.lmc"
|
28
|
+
#
|
29
|
+
# LocalMemCache.new :filename=>"./foo.lmc", :min_alloc_size => 512
|
24
30
|
#
|
25
31
|
# You must supply at least a :namespace or :filename parameter
|
26
32
|
# The size_mb defaults to 1024 (1 GB).
|
27
33
|
#
|
34
|
+
# The :min_alloc_size parameter was introduced to help with use cases that
|
35
|
+
# intend to use a hash table with growing values. This is currently not
|
36
|
+
# handled well by the internal allocator as it will end up with a large list
|
37
|
+
# of unusable free blocks. By setting the :min_alloc_size parameter you
|
38
|
+
# help the allocator to plan better ahead.
|
39
|
+
#
|
28
40
|
# If you use the :namespace parameter, the .lmc file for your namespace will
|
29
41
|
# reside in /var/tmp/localmemcache. This can be overriden by setting the
|
30
42
|
# LMC_NAMESPACES_ROOT_PATH variable in the environment.
|
@@ -75,6 +75,7 @@ static VALUE LocalMemCache;
|
|
75
75
|
static VALUE lmc_rb_sym_namespace;
|
76
76
|
static VALUE lmc_rb_sym_filename;
|
77
77
|
static VALUE lmc_rb_sym_size_mb;
|
78
|
+
static VALUE lmc_rb_sym_min_alloc_size;
|
78
79
|
static VALUE lmc_rb_sym_force;
|
79
80
|
|
80
81
|
/* :nodoc: */
|
@@ -118,7 +119,8 @@ static VALUE LocalMemCache__new2(VALUE klass, VALUE o) {
|
|
118
119
|
local_memcache_t *l = local_memcache_create(
|
119
120
|
rstring_ptr_null(rb_hash_aref(o, lmc_rb_sym_namespace)),
|
120
121
|
rstring_ptr_null(rb_hash_aref(o, lmc_rb_sym_filename)),
|
121
|
-
double_value(rb_hash_aref(o, lmc_rb_sym_size_mb)),
|
122
|
+
double_value(rb_hash_aref(o, lmc_rb_sym_size_mb)),
|
123
|
+
long_value(rb_hash_aref(o, lmc_rb_sym_min_alloc_size)), &e);
|
122
124
|
if (!l) rb_lmc_raise_exception(&e);
|
123
125
|
rb_lmc_handle_t *h = calloc(1, sizeof(rb_lmc_handle_t));
|
124
126
|
if (!h) rb_raise(rb_eRuntimeError, "memory allocation error");
|
@@ -489,6 +491,7 @@ void Init_rblocalmemcache() {
|
|
489
491
|
lmc_rb_sym_namespace = ID2SYM(rb_intern("namespace"));
|
490
492
|
lmc_rb_sym_filename = ID2SYM(rb_intern("filename"));
|
491
493
|
lmc_rb_sym_size_mb = ID2SYM(rb_intern("size_mb"));
|
494
|
+
lmc_rb_sym_min_alloc_size = ID2SYM(rb_intern("min_alloc_size"));
|
492
495
|
lmc_rb_sym_force = ID2SYM(rb_intern("force"));
|
493
496
|
rb_require("localmemcache.rb");
|
494
497
|
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
$DIR=File.dirname(__FILE__)
|
2
|
+
['.', '..', '../ruby-binding/'].each {|p| $:.unshift File.join($DIR, p) }
|
3
|
+
|
4
|
+
require 'bacon'
|
5
|
+
require 'localmemcache'
|
6
|
+
|
7
|
+
Bacon.summary_on_exit
|
8
|
+
|
9
|
+
LocalMemCache.drop :namespace => "speed-comparison", :force => true
|
10
|
+
$lm2 = LocalMemCache.new :namespace=>"speed-comparison", :min_alloc_size => 1024
|
11
|
+
|
12
|
+
def compare_speed(n)
|
13
|
+
|
14
|
+
puts "LocalMemCache"
|
15
|
+
measure_time(n) {
|
16
|
+
r = rand(10000).to_s
|
17
|
+
v = $lm2.get(r)
|
18
|
+
$lm2.set(r, "#{v}#{r}")
|
19
|
+
}
|
20
|
+
|
21
|
+
puts "Ruby Hash of Strings"
|
22
|
+
$hh = {}
|
23
|
+
measure_time(n) {
|
24
|
+
r = rand(10000).to_s
|
25
|
+
v = $hh[r]
|
26
|
+
$hh[r] = "#{v}#{r}"
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_gdbm(n)
|
31
|
+
require 'gdbm'
|
32
|
+
|
33
|
+
puts "GDBM"
|
34
|
+
h = GDBM.new("/tmp/fruitstore.db")
|
35
|
+
measure_time(n) {
|
36
|
+
r = rand(10000).to_s
|
37
|
+
h[r] = r
|
38
|
+
h[r]
|
39
|
+
}
|
40
|
+
h.close
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def measure_time(c, &block)
|
45
|
+
_then = Time.now
|
46
|
+
c.times { block.call }
|
47
|
+
now = Time.now
|
48
|
+
puts "#{(now - _then)*1000} ms"
|
49
|
+
end
|
50
|
+
|
51
|
+
compare_speed(200_000)
|
52
|
+
#test_gdbm(2_000_000)
|
53
|
+
|
54
|
+
#$stdout.write "ht shm setting x 20000: "
|
55
|
+
#tmeasure (2_000_000) {
|
56
|
+
# v = $lm2.get("f").to_i + 1
|
57
|
+
# #puts "v:#{v}"
|
58
|
+
# $lm2.set("f", v)
|
59
|
+
#}
|
60
|
+
#puts "foo: #{$lm2.get("f")}"
|
61
|
+
|
data/src/tests/lmc.rb
CHANGED
@@ -10,7 +10,7 @@ LocalMemCache.drop :namespace => "test", :force => true
|
|
10
10
|
$lm = LocalMemCache.new :namespace=>"test", :size_mb => 20
|
11
11
|
|
12
12
|
LocalMemCache.drop :namespace => "test-small", :force => true
|
13
|
-
$lms = LocalMemCache.new :namespace=>"test-small", :size_mb =>
|
13
|
+
$lms = LocalMemCache.new :namespace=>"test-small", :size_mb => 1;
|
14
14
|
|
15
15
|
describe 'LocalMemCache' do
|
16
16
|
|
@@ -72,7 +72,7 @@ describe 'LocalMemCache' do
|
|
72
72
|
|
73
73
|
it 'should support size' do
|
74
74
|
LocalMemCache.drop :namespace =>"size-test", :force=>true
|
75
|
-
ll = LocalMemCache.new :namespace => "size-test", :size_mb =>
|
75
|
+
ll = LocalMemCache.new :namespace => "size-test", :size_mb => 1
|
76
76
|
ll.size.should.equal 0
|
77
77
|
ll[:one] = 1
|
78
78
|
ll.size.should.equal 1
|
@@ -98,7 +98,7 @@ describe 'LocalMemCache' do
|
|
98
98
|
|
99
99
|
it 'should support filename parameters' do
|
100
100
|
LocalMemCache.drop :filename => ".tmp.a.lmc", :force => true
|
101
|
-
lm = LocalMemCache.new :filename => ".tmp.a.lmc", :size_mb =>
|
101
|
+
lm = LocalMemCache.new :filename => ".tmp.a.lmc", :size_mb => 1
|
102
102
|
lm[:boo] = 1
|
103
103
|
lm.size.should.equal 1
|
104
104
|
File.exists?(".tmp.a.lmc").should.be.true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: localmemcache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven C. Koehler
|
@@ -9,11 +9,18 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-08-10 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description:
|
16
|
+
description: |+
|
17
|
+
|
18
|
+
Localmemcache is a library for C and ruby that aims to provide
|
19
|
+
an interface similar to memcached but for accessing local data instead of
|
20
|
+
remote data. It's based on mmap()'ed shared memory for maximum speed.
|
21
|
+
Since version 0.3.0 it supports persistence, also making it a fast
|
22
|
+
alternative to GDBM and Berkeley DB.
|
23
|
+
|
17
24
|
email: schween@snafu.de
|
18
25
|
executables: []
|
19
26
|
|
@@ -119,6 +126,8 @@ files:
|
|
119
126
|
- src/tests/allocfailure.rb
|
120
127
|
- src/tests/bacon.rb
|
121
128
|
- src/tests/bench
|
129
|
+
- src/tests/bench-append
|
130
|
+
- src/tests/bench-append.rb
|
122
131
|
- src/tests/bench.rb
|
123
132
|
- src/tests/bench_keys
|
124
133
|
- src/tests/bench_keys.rb
|
@@ -144,6 +153,8 @@ files:
|
|
144
153
|
- src/tests/ttrandom_pair.rb
|
145
154
|
has_rdoc: true
|
146
155
|
homepage: http://localmemcache.rubyforge.org/
|
156
|
+
licenses: []
|
157
|
+
|
147
158
|
post_install_message:
|
148
159
|
rdoc_options: []
|
149
160
|
|
@@ -164,9 +175,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
175
|
requirements: []
|
165
176
|
|
166
177
|
rubyforge_project: localmemcache
|
167
|
-
rubygems_version: 1.
|
178
|
+
rubygems_version: 1.3.3
|
168
179
|
signing_key:
|
169
|
-
specification_version:
|
180
|
+
specification_version: 3
|
170
181
|
summary: A persistent key-value database based on mmap()'ed shared memory.
|
171
182
|
test_files: []
|
172
183
|
|