localmemcache 0.2.2 → 0.3.0

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.
Files changed (64) hide show
  1. data/README +18 -11
  2. data/Rakefile +22 -7
  3. data/VERSION +1 -1
  4. data/bench/common.rb +7 -0
  5. data/bench/gdbm_vs_lmc +10 -0
  6. data/bench/gdbm_vs_lmc.rb +29 -0
  7. data/bench/lmc_bench +11 -0
  8. data/bench/lmc_bench.rb +27 -0
  9. data/bench/memcached_bench +8 -0
  10. data/bench/memcached_bench.rb +19 -0
  11. data/bench/tyrant_bench +10 -0
  12. data/bench/tyrant_bench.rb +19 -0
  13. data/example/hello.c +1 -1
  14. data/site/doc/classes/LocalMemCache/ArgError.html +113 -0
  15. data/site/doc/classes/LocalMemCache/InitError.html +113 -0
  16. data/site/doc/classes/LocalMemCache/LocalMemCacheError.html +111 -0
  17. data/site/doc/classes/LocalMemCache/LockError.html +113 -0
  18. data/site/doc/classes/LocalMemCache/LockTimedOut.html +113 -0
  19. data/site/doc/classes/LocalMemCache/MemoryPoolClosed.html +113 -0
  20. data/site/doc/classes/LocalMemCache/MemoryPoolFull.html +113 -0
  21. data/site/doc/classes/LocalMemCache/OutOfMemoryError.html +113 -0
  22. data/site/doc/classes/LocalMemCache/RecoveryFailed.html +113 -0
  23. data/site/doc/classes/LocalMemCache/ShmError.html +113 -0
  24. data/site/doc/classes/LocalMemCache/ShmLockFailed.html +113 -0
  25. data/site/doc/classes/LocalMemCache/ShmUnlockFailed.html +113 -0
  26. data/site/doc/classes/LocalMemCache.html +515 -0
  27. data/site/doc/classes/LocalMemCache.src/M000001.html +19 -0
  28. data/site/doc/classes/LocalMemCache.src/M000002.html +18 -0
  29. data/site/doc/classes/LocalMemCache.src/M000003.html +18 -0
  30. data/site/doc/classes/LocalMemCache.src/M000004.html +39 -0
  31. data/site/doc/classes/LocalMemCache.src/M000005.html +29 -0
  32. data/site/doc/classes/LocalMemCache.src/M000006.html +23 -0
  33. data/site/doc/classes/LocalMemCache.src/M000007.html +23 -0
  34. data/site/doc/classes/LocalMemCache.src/M000008.html +22 -0
  35. data/site/doc/classes/LocalMemCache.src/M000009.html +24 -0
  36. data/site/doc/classes/LocalMemCache.src/M000010.html +24 -0
  37. data/site/doc/classes/LocalMemCache.src/M000011.html +22 -0
  38. data/site/doc/classes/LocalMemCache.src/M000012.html +22 -0
  39. data/site/doc/created.rid +1 -0
  40. data/site/doc/files/__/src/ruby-binding/extconf_rb.html +108 -0
  41. data/site/doc/files/__/src/ruby-binding/localmemcache_rb.html +108 -0
  42. data/site/doc/files/__/src/ruby-binding/rblocalmemcache_c.html +101 -0
  43. data/site/doc/fr_class_index.html +39 -0
  44. data/site/doc/fr_file_index.html +28 -0
  45. data/site/doc/fr_method_index.html +38 -0
  46. data/site/doc/index.html +24 -0
  47. data/site/doc/rdoc-style.css +208 -0
  48. data/site/index.html +50 -46
  49. data/src/lmc_common.c +22 -0
  50. data/src/lmc_common.h +4 -0
  51. data/src/lmc_hashtable.h +1 -1
  52. data/src/lmc_lock.c +17 -3
  53. data/src/lmc_shm.c +4 -2
  54. data/src/lmc_valloc.c +6 -5
  55. data/src/lmc_valloc.h +1 -0
  56. data/src/localmemcache.c +56 -35
  57. data/src/localmemcache.h +161 -4
  58. data/src/ruby-binding/localmemcache.rb +48 -16
  59. data/src/ruby-binding/rblocalmemcache.c +131 -24
  60. data/src/tests/bench.rb +1 -1
  61. data/src/tests/lmc.rb +11 -2
  62. metadata +48 -7
  63. data/INTERNALS +0 -26
  64. data/example/hello.bin +0 -0
@@ -0,0 +1,208 @@
1
+
2
+ body {
3
+ font-family: Verdana,Arial,Helvetica,sans-serif;
4
+ font-size: 90%;
5
+ margin: 0;
6
+ margin-left: 40px;
7
+ padding: 0;
8
+ background: white;
9
+ }
10
+
11
+ h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
12
+ h1 { font-size: 150%; }
13
+ h2,h3,h4 { margin-top: 1em; }
14
+
15
+ a { background: #eef; color: #039; text-decoration: none; }
16
+ a:hover { background: #039; color: #eef; }
17
+
18
+ /* Override the base stylesheet's Anchor inside a table cell */
19
+ td > a {
20
+ background: transparent;
21
+ color: #039;
22
+ text-decoration: none;
23
+ }
24
+
25
+ /* and inside a section title */
26
+ .section-title > a {
27
+ background: transparent;
28
+ color: #eee;
29
+ text-decoration: none;
30
+ }
31
+
32
+ /* === Structural elements =================================== */
33
+
34
+ div#index {
35
+ margin: 0;
36
+ margin-left: -40px;
37
+ padding: 0;
38
+ font-size: 90%;
39
+ }
40
+
41
+
42
+ div#index a {
43
+ margin-left: 0.7em;
44
+ }
45
+
46
+ div#index .section-bar {
47
+ margin-left: 0px;
48
+ padding-left: 0.7em;
49
+ background: #ccc;
50
+ font-size: small;
51
+ }
52
+
53
+
54
+ div#classHeader, div#fileHeader {
55
+ width: auto;
56
+ color: white;
57
+ padding: 0.5em 1.5em 0.5em 1.5em;
58
+ margin: 0;
59
+ margin-left: -40px;
60
+ border-bottom: 3px solid #006;
61
+ }
62
+
63
+ div#classHeader a, div#fileHeader a {
64
+ background: inherit;
65
+ color: white;
66
+ }
67
+
68
+ div#classHeader td, div#fileHeader td {
69
+ background: inherit;
70
+ color: white;
71
+ }
72
+
73
+
74
+ div#fileHeader {
75
+ background: #057;
76
+ }
77
+
78
+ div#classHeader {
79
+ background: #048;
80
+ }
81
+
82
+
83
+ .class-name-in-header {
84
+ font-size: 180%;
85
+ font-weight: bold;
86
+ }
87
+
88
+
89
+ div#bodyContent {
90
+ padding: 0 1.5em 0 1.5em;
91
+ }
92
+
93
+ div#description {
94
+ padding: 0.5em 1.5em;
95
+ background: #efefef;
96
+ border: 1px dotted #999;
97
+ }
98
+
99
+ div#description h1,h2,h3,h4,h5,h6 {
100
+ color: #125;;
101
+ background: transparent;
102
+ }
103
+
104
+ div#validator-badges {
105
+ text-align: center;
106
+ }
107
+ div#validator-badges img { border: 0; }
108
+
109
+ div#copyright {
110
+ color: #333;
111
+ background: #efefef;
112
+ font: 0.75em sans-serif;
113
+ margin-top: 5em;
114
+ margin-bottom: 0;
115
+ padding: 0.5em 2em;
116
+ }
117
+
118
+
119
+ /* === Classes =================================== */
120
+
121
+ table.header-table {
122
+ color: white;
123
+ font-size: small;
124
+ }
125
+
126
+ .type-note {
127
+ font-size: small;
128
+ color: #DEDEDE;
129
+ }
130
+
131
+ .xxsection-bar {
132
+ background: #eee;
133
+ color: #333;
134
+ padding: 3px;
135
+ }
136
+
137
+ .section-bar {
138
+ color: #333;
139
+ border-bottom: 1px solid #999;
140
+ margin-left: -20px;
141
+ }
142
+
143
+
144
+ .section-title {
145
+ background: #79a;
146
+ color: #eee;
147
+ padding: 3px;
148
+ margin-top: 2em;
149
+ margin-left: -30px;
150
+ border: 1px solid #999;
151
+ }
152
+
153
+ .top-aligned-row { vertical-align: top }
154
+ .bottom-aligned-row { vertical-align: bottom }
155
+
156
+ /* --- Context section classes ----------------------- */
157
+
158
+ .context-row { }
159
+ .context-item-name { font-family: monospace; font-weight: bold; color: black; }
160
+ .context-item-value { font-size: small; color: #448; }
161
+ .context-item-desc { color: #333; padding-left: 2em; }
162
+
163
+ /* --- Method classes -------------------------- */
164
+ .method-detail {
165
+ background: #efefef;
166
+ padding: 0;
167
+ margin-top: 0.5em;
168
+ margin-bottom: 1em;
169
+ border: 1px dotted #ccc;
170
+ }
171
+ .method-heading {
172
+ color: black;
173
+ background: #ccc;
174
+ border-bottom: 1px solid #666;
175
+ padding: 0.2em 0.5em 0 0.5em;
176
+ }
177
+ .method-signature { color: black; background: inherit; }
178
+ .method-name { font-weight: bold; }
179
+ .method-args { font-style: italic; }
180
+ .method-description { padding: 0 0.5em 0 0.5em; }
181
+
182
+ /* --- Source code sections -------------------- */
183
+
184
+ a.source-toggle { font-size: 90%; }
185
+ div.method-source-code {
186
+ background: #262626;
187
+ color: #ffdead;
188
+ margin: 1em;
189
+ padding: 0.5em;
190
+ border: 1px dashed #999;
191
+ overflow: hidden;
192
+ }
193
+
194
+ div.method-source-code pre { color: #ffdead; overflow: hidden; }
195
+
196
+ /* --- Ruby keyword styles --------------------- */
197
+
198
+ .standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
199
+
200
+ .ruby-constant { color: #7fffd4; background: transparent; }
201
+ .ruby-keyword { color: #00ffff; background: transparent; }
202
+ .ruby-ivar { color: #eedd82; background: transparent; }
203
+ .ruby-operator { color: #00ffee; background: transparent; }
204
+ .ruby-identifier { color: #ffdead; background: transparent; }
205
+ .ruby-node { color: #ffa07a; background: transparent; }
206
+ .ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
207
+ .ruby-regexp { color: #ffa07a; background: transparent; }
208
+ .ruby-value { color: #7fffd4; background: transparent; }
data/site/index.html CHANGED
@@ -7,44 +7,29 @@
7
7
  <body>
8
8
 
9
9
  <div id="content">
10
- <h1>The beauty of memcached.&nbsp;&nbsp;For local data.&nbsp;&nbsp;Blazingly fast.</h1>
10
+ <h1>A persistent key-value database based on mmap()'ed shared memory</h1>
11
11
 
12
12
  <p><b>Localmemcache</b> is a library for C and ruby that aims to provide
13
13
  an interface similar to memcached but for accessing local data instead of
14
14
  remote data. It's based on <b>mmap()</b>'ed shared memory for maximum speed.
15
-
16
- <h2>2009-04-05: Changes for 0.2.1</h2>
17
-
18
- <li>Fixed a bug that prevented setting values in the hashtable</li>
19
- <li>Accessing a closed memory cache does no longer result in a crash</li>
20
- <li><b>Speed improvements</b>: On my machine localmemcache is now only
21
- about <b>20</b>% slower than Ruby's hash (<b>0.2.0</b> was about
22
- <b>40</b>% slower)</li>
23
- <li><b>OS X is now officially not supported</b> as it lacks sem_timedwait and
24
- sem_getvalue (You still can force a build but it won't be able to
25
- recover from crashes.)</li>
26
- <li>The environment variable <b>LMC_NAMESPACES_ROOT_PATH</b> can now be
27
- used to override the default, which is <b>/var/tmp/localmemcache</b></li>
28
-
29
-
30
- <h2>2009-03-30: New features in 0.2.0</h2>
31
-
32
- <li><b>Logging</b>: In case your application is terminated while
33
- accessing the shared memory (eg by <b>kill -9</b>), it is now able to
34
- <b>restore the integrity of your data</b>.</li>
35
- <li><b>\0 character</b> can now be used in <b>keys</b> and
36
- <b>values</b></li>
37
- <li>The ruby binding now features a <b>keys()</b> method.</b>
38
- <li>Added a <b>C API</b>. See <a href="http://github.com/sck/localmemcache/blob/8c753f74c53b107d271975bedcc1f91a3dbd6961/src/localmemcache.h">localmemcache.h</a></li>
39
-
40
- <h2>Supported Systems</h2>
41
-
42
- <li>Unix (for <b>mmap())</b></li>
43
- <li>OS X is currently not supported because it doesn't have
44
- sem_timedwait() and sem_getvalue()</li>
45
- <li>A CPU architecture with more than <b>32 bits</b> is recommended, since
46
- otherwise you might run out of virtual address space when you use larger
47
- shared memory segments.</li>
15
+ Since version 0.3.0 it supports persistence, also making it a fast
16
+ alternative to GDBM and Berkeley DB.
17
+
18
+ <h2>Key features as of 0.3.0 (2009-04-17)</h2>
19
+ <li><a href="#performance">blazingly fast</a></li>
20
+ <li>persistent</li>
21
+ <li>parallel writes are supported by default</li>
22
+ <li>uses transactions internally to avoid data corruption</li>
23
+ <li>lightweight: the core library is just about <b>1400</b> lines of <b>C</b> code</li>
24
+
25
+ <h2>Requirements</h2>
26
+ <li>a &gt;=64bit Unix</li>
27
+ <li>a file system that offers <a href="http://en.wikipedia.org/wiki/Sparse_file">sparse files</a></li>
28
+ Note for <b>OS X</b>: <b>OS X</b> disqualifies as <b>HFS+</b> doesn't
29
+ have sparse files and <b>sem_timedwait</b>() and <b>sem_getvalue</b>() aren't
30
+ supported as well.
31
+ Note for <b>FreeBSD</b>: It has been reported that Localmemcache
32
+ sometimes hangs there, it is not yet clear what the problem is.
48
33
 
49
34
  <h2>Install</h2>
50
35
 
@@ -53,19 +38,24 @@ shared memory segments.</li>
53
38
  <pre><code>gem install localmemcache
54
39
  </code></pre>
55
40
 
41
+
56
42
  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>.
57
43
 
58
44
  <h2>Using</h2>
45
+ <b>API</b>:&nbsp;<a href="http://github.com/sck/localmemcache/blob/e980ba949034a349dbf0e6f8f9ef77bbe3e3e314/src/localmemcache.h">C</a>|<a href="http://localmemcache.rubyforge.org/doc/">Ruby</a><br>
59
46
  <p><pre><code>require 'localmemcache'
60
- $lm = LocalMemCache.new :namespace => :viewcounters
47
+ # 1. the memcached way
48
+ # $lm = LocalMemCache.new :namespace => :viewcounters
49
+ # 2. the GDBM way
50
+ $lm = LocalMemCache.new :filename => "./viewcounters.lmc"
61
51
  $lm[:foo] = 1
62
52
  $lm[:foo]
63
53
  $lm.delete(:foo)
64
54
  </code></pre>
65
- (C version of this example: <a href="http://github.com/sck/localmemcache/blob/8c753f74c53b107d271975bedcc1f91a3dbd6961/example/hello.c">hello.c</a>)
55
+ (C version of this example: <a href="http://github.com/sck/localmemcache/blob/e980ba949034a349dbf0e6f8f9ef77bbe3e3e314/example/hello.c">hello.c</a>)
66
56
  </p>
67
- <a href="http://github.com/sck/localmemcache/tree/master">Read more</a>.
68
57
 
58
+ <a name="performance" id="performance"></a>
69
59
  <h2>Performance</h2>
70
60
 
71
61
  <p>Here's a quick speed comparison, made on an
@@ -79,14 +69,22 @@ Ruby benchmark pseudo code:
79
69
  </code></pre>
80
70
 
81
71
  <pre>
82
- MemCache: <b>253,326.122</b> ms
83
- LocalMemCache 0.2.1: <b>5,799.225</b> ms
84
- Ruby's Hash: <b>4,963.313</b> ms
72
+ Tokyo Tyrant: <b>298,226.197</b> ms
73
+ MemCache: <b>253,326.122</b> ms
74
+ GDBM: <b>24,226.116</b> ms
75
+ Localmemcache 0.2.2: <b>5,799.225</b> ms
76
+ Localmemcache 0.3.0: <b>5,300.055</b> ms
77
+ Ruby Hash of Strings: <b>4,963.313</b> ms
85
78
  </pre>
79
+ (<a href="http://github.com/sck/localmemcache/tree/e980ba949034a349dbf0e6f8f9ef77bbe3e3e314/bench">Code of the benchmarks used</a>)
86
80
 
87
- So, on my machine <b>Localmemcache</b> 0.2.1 is about <b>43</b> times
88
- faster than using memcached locally, and about <b>20</b>% slower than
89
- Ruby's hash.
81
+ <p>
82
+
83
+ So, on my machine, using <b>Localmemcache</b> 0.3.0 to store key-value
84
+ data on disk is about <b>10</b>% slower than keeping them in memory in a
85
+ Ruby hash of strings. Also keep in mind that of the above mentioned
86
+ software components <b>Tokyo Tyrant</b> is the only one that offers
87
+ persistence and parallel writes like <b>Localmemcache</b> does.
90
88
 
91
89
  <h2>Source code</h2>
92
90
 
@@ -96,10 +94,16 @@ can be retrieved by executing</p>
96
94
  <pre><code>git clone git://github.com/sck/localmemcache.git
97
95
  </code></pre>
98
96
 
99
- <h2>Read on</h2>
97
+ <h2>Tips for backups</h1>
98
+
99
+ Note that you cannot copy Localmemcache's .lmc files while other
100
+ processes are making changes to the data, this will likely result in a
101
+ corrupt backup. So you need to make sure that none of your processes are
102
+ writing during the time you do an backup. As for copying sparse files,
103
+ <b>cp</b> recognizes them automatically, with <b>tar</b> you need to use
104
+ the <b>-S</b> option.
100
105
 
101
- A bit of documenation on how <b>localmemcache</b> <a
102
- href="http://github.com/sck/localmemcache/blob/96b5e0863e1da7f17e249a6c8884984e0c23ee2f/INTERNALS">works</a>.
106
+ <h2><a href="http://localmemcache.rubyforge.org/doc/classes/LocalMemCache.html">Read on / RDoc</a></h2>
103
107
 
104
108
  <h2>License</h2>
105
109
 
data/src/lmc_common.c CHANGED
@@ -7,6 +7,7 @@
7
7
  #include <sys/types.h>
8
8
  #include <unistd.h>
9
9
  #include <stdlib.h>
10
+ #include <string.h>
10
11
 
11
12
  int lmc_test_crash_enabled = 0;
12
13
  int lmc_showed_status = 0;
@@ -41,3 +42,24 @@ size_t lmc_test_valloc_fail(const char *file, int line, const char *function,
41
42
  return lmc_valloc(base, s);
42
43
  }
43
44
 
45
+ void lmc_clean_string(char *result, const char *source) {
46
+ size_t n = strlen(source);
47
+ if (n > 256) { n = 256; }
48
+ const char *s = source;
49
+ char *d = result;
50
+ char ch;
51
+ for (; n--; d++, s++) {
52
+ ch = *s;
53
+ if ((ch >= 'a' && ch <= 'z') ||
54
+ (ch >= 'A' && ch <= 'Z')) {
55
+ *d = ch;
56
+ } else {
57
+ *d = '-';
58
+ }
59
+ }
60
+ *d = 0x0;
61
+ }
62
+
63
+ int lmc_is_filename(const char *s) {
64
+ return strlen(s) > 1 && (s[0] == '/' || (s[0] == '.' && s[1] == '/'));
65
+ }
data/src/lmc_common.h CHANGED
@@ -5,6 +5,8 @@
5
5
  #ifndef _LMC_COMMON_H_INCLUDED_
6
6
  #define _LMC_COMMON_H_INCLUDED_
7
7
 
8
+ #define LMC_DB_VERSION 0
9
+
8
10
  extern int lmc_test_crash_enabled;
9
11
  #ifdef DO_TEST_CRASH
10
12
  #define LMC_TEST_CRASH lmc_test_crash(__FILE__, __LINE__, __FUNCTION__);
@@ -21,6 +23,8 @@ extern int lmc_test_crash_enabled;
21
23
  void lmc_test_crash(const char* file, int line, const char *function);
22
24
  size_t lmc_test_valloc_fail(const char *file, int line, const char *function,
23
25
  void *base, size_t s);
26
+ void lmc_clean_string(char *result, const char *source);
27
+ int lmc_is_filename(const char *s);
24
28
 
25
29
  #endif
26
30
 
data/src/lmc_hashtable.h CHANGED
@@ -16,7 +16,7 @@ typedef struct {
16
16
  va_string_t va_value;
17
17
  } ht_hash_entry_t;
18
18
 
19
- #define LMC_HT_BUCKETS 499
19
+ #define LMC_HT_BUCKETS 20731
20
20
  #define LMC_ITERATOR_P(n) int ((n)) \
21
21
  (void *ctx, const char *key, const char *value)
22
22
 
data/src/lmc_lock.c CHANGED
@@ -1,3 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2009, Sven C. Koehler
3
+ */
4
+
1
5
  #include <stdio.h>
2
6
  #include <stdlib.h>
3
7
  #include <fcntl.h>
@@ -8,11 +12,19 @@
8
12
  #include <unistd.h>
9
13
  #include <time.h>
10
14
  #include "lmc_lock.h"
15
+ #include "lmc_common.h"
16
+
17
+ void lmc_namespacify(char *result, const char *s) {
18
+ if (lmc_is_filename(s)) { lmc_clean_string(result, s); }
19
+ else { strcpy(result, s); }
20
+ }
11
21
 
12
- lmc_lock_t *lmc_lock_init(const char *namespace, int init, lmc_error_t *e) {
22
+ lmc_lock_t *lmc_lock_init(const char *ns, int init, lmc_error_t *e) {
23
+ char namespace[1024];
24
+ lmc_namespacify(namespace, ns);
13
25
  lmc_lock_t *l = malloc(sizeof(lmc_lock_t));
14
26
  if (!l) return NULL;
15
- strncpy((char *)&l->namespace, namespace, 1023);
27
+ snprintf((char *)&l->namespace, 1023, "%s", namespace);
16
28
 
17
29
  lmc_handle_error((l->sem = sem_open(l->namespace, O_CREAT, 0600, init)) ==
18
30
  NULL, "sem_open", "LockError", e);
@@ -20,7 +32,9 @@ lmc_lock_t *lmc_lock_init(const char *namespace, int init, lmc_error_t *e) {
20
32
  return l;
21
33
  }
22
34
 
23
- int lmc_clear_namespace_lock(const char *namespace) {
35
+ int lmc_clear_namespace_lock(const char *ns) {
36
+ char namespace[1024];
37
+ lmc_namespacify(namespace, ns);
24
38
  lmc_error_t e;
25
39
  lmc_lock_t *l = lmc_lock_init(namespace, 1, &e);
26
40
  lmc_lock_repair(l);
data/src/lmc_shm.c CHANGED
@@ -11,6 +11,7 @@
11
11
  #include <fcntl.h>
12
12
  #include <sys/mman.h>
13
13
 
14
+ #include "lmc_common.h"
14
15
  #include "lmc_shm.h"
15
16
 
16
17
  const char *lmc_namespace_root_path() {
@@ -37,7 +38,8 @@ void lmc_shm_ensure_root_path() {
37
38
  }
38
39
 
39
40
  void lmc_file_path_for_namespace(char *result, const char *ns) {
40
- snprintf(result, 1023, "%s/%s.lmc", lmc_namespace_root_path(), ns);
41
+ if (lmc_is_filename(ns)) { snprintf(result, 1023, "%s", ns); }
42
+ else { snprintf(result, 1023, "%s/%s.lmc", lmc_namespace_root_path(), ns); }
41
43
  }
42
44
 
43
45
  int lmc_does_namespace_exist(const char *ns) {
@@ -78,7 +80,7 @@ lmc_shm_t *lmc_shm_create(const char* namespace, size_t size, int use_persistenc
78
80
  STD_OUT_OF_MEMORY_ERROR("lmc_shm_create");
79
81
  return NULL;
80
82
  }
81
- strncpy((char *)&mc->namespace, namespace, 1023);
83
+ snprintf((char *)&mc->namespace, 1023, "%s", namespace);
82
84
  mc->use_persistence = 0;
83
85
  mc->size = size;
84
86
 
data/src/lmc_valloc.c CHANGED
@@ -69,7 +69,7 @@ lmc_mem_status_t lmc_status(void *base, char *where) {
69
69
  ms.total_mem = md->total_size;
70
70
  while (c) {
71
71
  if (!lmc_is_va_valid(base, (void *)c - base)) {
72
- printf("lmc: [%s] invalid pointer detected: %zd...\n", where,
72
+ printf("[localmemcache] [%s] invalid pointer detected: %zd...\n", where,
73
73
  (void *)c - base);
74
74
  lmc_dump(base);
75
75
  abort();
@@ -108,7 +108,8 @@ void lmc_init_memory(void *ptr, size_t size) {
108
108
  size_t s = size - sizeof(lmc_mem_descriptor_t);
109
109
  md->first_free = sizeof(lmc_mem_descriptor_t);
110
110
  md->magic = 0xF00D;
111
- md->locked = 0;
111
+ md->version = LMC_DB_VERSION;
112
+ md->locked = 1;
112
113
  md->total_size = s;
113
114
  lmc_mem_chunk_descriptor_t *c = ptr + sizeof(lmc_mem_descriptor_t);
114
115
  c->next = 0;
@@ -319,7 +320,7 @@ void lmc_free(void *base, size_t chunk) {
319
320
  if (chunk == 0) { return; }
320
321
  if (!(chunk >= sizeof(lmc_mem_descriptor_t) + sizeof(size_t)) ||
321
322
  !lmc_is_va_valid(base, chunk)) {
322
- printf("lmc_free: Invalid pointer: %zd\n", chunk);
323
+ fprintf(stderr, "[localmemcache] lmc_free: Invalid pointer: %zd\n", chunk);
323
324
  return;
324
325
  }
325
326
  size_t va_used_chunk = chunk - sizeof(size_t);
@@ -396,8 +397,8 @@ int lmc_um_mark(void *base, char *bf, size_t va, size_t size) {
396
397
  lmc_mem_descriptor_t *md = base;
397
398
  if ((va > sizeof(lmc_mem_descriptor_t)) &&
398
399
  (!lmc_is_va_valid(base, va) || !lmc_is_va_valid(base, va + size))) {
399
- printf("lmc: Error: VA start out of range: va: %zd - %zd max %zd!\n",
400
- va, va + size, md->total_size);
400
+ printf("[localmemcache] Error: VA start out of range: "
401
+ "va: %zd - %zd max %zd!\n", va, va + size, md->total_size);
401
402
  return 0;
402
403
  }
403
404
  if (!lmc_um_check_unmarked(base, bf, va, size)) return 0;
data/src/lmc_valloc.h CHANGED
@@ -26,6 +26,7 @@ typedef struct {
26
26
  size_t magic;
27
27
  size_t va_hash;
28
28
  int locked;
29
+ size_t version;
29
30
  lmc_log_descriptor_t log;
30
31
  } lmc_mem_descriptor_t;
31
32