localmemcache 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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