localmemcache 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/configure.in ADDED
@@ -0,0 +1,42 @@
1
+ AC_INIT(${srcdir}/src/lmc_config.h.in)
2
+ AC_CONFIG_HEADER(${srcdir}/src/lmc_config.h)
3
+ AC_PROG_CC
4
+ AC_SUBST(CC)
5
+ AC_PROG_RANLIB
6
+ AC_SUBST(RANLIB)
7
+
8
+ AC_MSG_CHECKING([version])
9
+ VERSION=`cat ${srcdir}/VERSION`
10
+ AC_SUBST(VERSION)
11
+ AC_MSG_RESULT([$VERSION])
12
+
13
+ AC_MSG_CHECKING([installation directory prefix])
14
+
15
+ if test "$prefix" = "NONE"; then
16
+ if test "x$PREFIX" != "x" ; then
17
+ prefix=$PREFIX
18
+ else
19
+ prefix=/usr/local
20
+ fi
21
+ fi
22
+ AC_PREFIX_DEFAULT($prefix)
23
+ PREFIX=$ac_default_prefix
24
+ PREFIX=$prefix
25
+ exec_prefix=$PREFIX
26
+ AC_SUBST(PREFIX)
27
+ AC_MSG_RESULT([$PREFIX])
28
+
29
+ AC_MSG_CHECKING([if inside RubyGems])
30
+ env > /tmp/lmc.env
31
+ AC_MSG_RESULT([$PREFIX])
32
+
33
+
34
+
35
+ #--------------------------------------------------------------------
36
+ # Propagate prefix argument as installation directory.
37
+ #--------------------------------------------------------------------
38
+ AC_SUBST(PREFIX)
39
+
40
+
41
+ AC_OUTPUT(src/Makefile)
42
+ AC_OUTPUT(Makefile)
data/site/index.html ADDED
@@ -0,0 +1,70 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
4
+ <title>Localmemcache</title>
5
+ <link type="text/css" rel="stylesheet" href="style.css" media="screen"/>
6
+ </head>
7
+ <body>
8
+
9
+ <div id="content">
10
+ <h1>Efficiently sharing a hashtable between processes on a local Unix machine.</h1>
11
+
12
+ <p><b>Localmemcache</b> aims to be faster than using <a href="http://www.danga.com/memcached/">memcached</a> locally by using shared memory and providing a similar interface for Ruby and C.
13
+
14
+ <h2>Install</h2>
15
+
16
+ <p>The Ruby binding is available as a Ruby Gem. It can be installed by executing</p>
17
+
18
+ <pre><code>gem install localmemcache
19
+ </code></pre>
20
+
21
+ <h2>Using</h2>
22
+ <p><pre><code>require 'localmemcache'
23
+ $lm = LocalMemCache.new :namespace => :viewcounters
24
+ $lm[:foo] = 1
25
+ $lm[:foo]
26
+ $lm.delete(:foo)
27
+ </code></pre>
28
+ </p>
29
+ <a href="http://github.com/sck/localmemcache/tree/master">Read more</a>.
30
+
31
+ <h2>Performance</h2>
32
+
33
+ <p>Here's a quick speed comparison, made on an
34
+ <b>Intel(R) Xeon(R) CPU E5205 @ 1.86GHz</b>:</p>
35
+ Benchmark pseudo code:
36
+ <pre><code>2_000_000.times {
37
+ index = rand(10000).to_s
38
+ $hash.set(index, index)
39
+ $hash.get(index)
40
+ }
41
+ </code></pre>
42
+
43
+ <pre>
44
+ MemCache: <b>253,326.122</b> ms
45
+ LocalMemCache: <b>6,055.552</b> ms
46
+ Ruby's Hash: <b>4,963.313</b> ms
47
+ </pre>
48
+
49
+ <b>Localmemcache</b> is about <b>40</b> times faster than using memcached
50
+ locally, and about <b>20%</b> slower than Ruby's hash.
51
+
52
+ <h2>Source code</h2>
53
+
54
+ <p>The source code is hosted on <a href="http://github.com/sck/localmemcache/tree/master">github</a>. It
55
+ can be retrieved by executing</p>
56
+
57
+ <pre><code>git clone git://github.com/sck/localmemcache.git
58
+ </code></pre>
59
+
60
+ <h2>License</h2>
61
+
62
+ <p>Copyright (c) 2009 Sven C. Koehler (schween at s n a f u dot de)<br>
63
+ Localmemcache is freely distributable under the terms of an
64
+ <a href="http://github.com/sck/localmemcache/blob/af51a7d10e7162551e0cb1cf1b1635c1c76fe8d2/COPYING">MIT-style license</a>.
65
+ </p>
66
+
67
+ </div>
68
+
69
+ </body>
70
+ </html>
data/site/style.css ADDED
@@ -0,0 +1,37 @@
1
+ body {
2
+ background: #FFF;
3
+ color: #333;
4
+ font-family: "Helvetica Neue", Helvetica, "Trebuchet MS", "Lucida Grande", Verdana, sans-serif;
5
+ line-height: 15pt;
6
+ margin: 0;
7
+ font-size: 12pt;
8
+ line-height: 1.6em;
9
+ }
10
+
11
+ h1, h2, h3, h4 {
12
+ color: #0;
13
+ padding: 0;
14
+ margin: 1em 0;
15
+ }
16
+
17
+ pre, code {
18
+ font-family: Courier;
19
+ font-size: 11pt;
20
+ overflow: auto;
21
+ }
22
+
23
+ a { color: #0088FF; text-decoration: none }
24
+ a:hover { color: #fff; background-color: #0088FF }
25
+
26
+ #content {
27
+ margin: 1em auto ;
28
+ max-width: 35em;
29
+ }
30
+
31
+ ol, ul { padding-left: 0; }
32
+
33
+ #content p {
34
+ }
35
+ #about {
36
+ list-style:none;
37
+ }
data/src/Makefile.in ADDED
@@ -0,0 +1,53 @@
1
+ CC=@CC@
2
+ VERSION=@VERSION@
3
+ TARGET=liblmc.a
4
+ CFLAGS=-Wall -Wunused -fPIC -O2
5
+ RUBY_LIB=rblocalmemcache.so
6
+ LDFLAGS=
7
+ AR=ar
8
+ RANLIB=@RANLIB@
9
+ PREFIX=@PREFIX@
10
+ LIBS=
11
+ OFILES= \
12
+ lmc_valloc.o \
13
+ lmc_error.o \
14
+ lmc_hashtable.o \
15
+ lmc_shm.o \
16
+ lmc_lock.o \
17
+ localmemcache.o
18
+
19
+ compile: $(TARGET)
20
+
21
+ ruby-binding: $(RUBY_LIB)
22
+
23
+ $(RUBY_LIB): $(TARGET)
24
+ cd ruby-binding; ruby extconf.rb
25
+ -$(MAKE) -C ruby-binding
26
+ cd tests; ruby extconf.rb
27
+ -$(MAKE) -C tests
28
+
29
+ $(TARGET): $(OFILES)
30
+ $(AR) r $@ $(OFILES)
31
+ $(RANLIB) $@
32
+
33
+ %.o: %.c
34
+ $(CC) $(CFLAGS) -c -o $@ $<
35
+
36
+ test: $(TARGET)
37
+ ./tests/runtest.sh
38
+
39
+ install: $(TARGET)
40
+ @echo "INSTALLING localmemcache to ${PREFIX}"
41
+ install -d -m755 ${PREFIX}/lib
42
+ install -d -m755 ${PREFIX}/include
43
+ install -m644 ${TARGET} ${PREFIX}/lib
44
+ @echo INSTALLING headers to ${PREFIX}/include
45
+ install -m644 lmc_config.h lmc_error.h lmc_hashtable.h lmc_lock.h \
46
+ lmc_shm.h lmc_valloc.h ${PREFIX}/include
47
+
48
+ clean:
49
+ rm -f *.log *.so *.a *.o tests/core tests/vgcore* \
50
+ tests/*.so tests/*.o ruby-binding/*.o ruby-binding/*.so
51
+
52
+ distclean: clean
53
+ rm -f lmc_config.h tests/Makefile ruby-binding/Makefile
@@ -0,0 +1,4 @@
1
+ #ifndef _LMC_CONFIG_H_INCLUDED_
2
+ #define _LMC_CONFIG_H_INCLUDED_
3
+
4
+ #endif
data/src/lmc_error.c ADDED
@@ -0,0 +1,18 @@
1
+ #include "lmc_error.h"
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+ #include <errno.h>
5
+ #include <string.h>
6
+
7
+ int lmc_handle_error(int check, const char *ctx, lmc_error_t *e) {
8
+ if (!check) { return LMC_OK; }
9
+ return lmc_handle_error_with_err_string(ctx, strerror(errno), e);
10
+ }
11
+
12
+ int lmc_handle_error_with_err_string(const char *ctx,
13
+ const char *error_msg, lmc_error_t *e) {
14
+ if (!e) { return LMC_OK; }
15
+ snprintf((char *)&e->error_str, 1023, "%s: %s", ctx, error_msg);
16
+ e->error_number = errno;
17
+ return LMC_ERROR;
18
+ }
data/src/lmc_error.h ADDED
@@ -0,0 +1,19 @@
1
+ /*
2
+ * Copyright (c) 2009, Sven C. Koehler
3
+ */
4
+
5
+ #ifndef _LMC_ERROR_H_
6
+ #define _LMC_ERROR_H_
7
+
8
+ #define LMC_OK 1
9
+ #define LMC_ERROR 0
10
+
11
+ typedef struct {
12
+ char error_str[1024];
13
+ int error_number;
14
+ } lmc_error_t;
15
+
16
+ int lmc_handle_error(int check, const char *ctx, lmc_error_t* e);
17
+ int lmc_handle_error_with_err_string(const char *ctx, const char* error_msg,
18
+ lmc_error_t* e);
19
+ #endif
@@ -0,0 +1,104 @@
1
+ /*
2
+ * Copyright (c) 2009, Sven C. Koehler
3
+ */
4
+
5
+ #include <stdio.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+
9
+ #include "lmc_hashtable.h"
10
+ #include "lmc_valloc.h"
11
+
12
+ size_t ht_strdup(void *base, const char *s) {
13
+ size_t va_s = lmc_valloc(base, strlen(s) + 1);
14
+ if (!va_s) { return 0; }
15
+ //memcpy(base + va_s, s, strlen(s) + 1);
16
+ strcpy(base + va_s, s);
17
+ return va_s;
18
+ }
19
+
20
+ unsigned long ht_hash_key(const char *s) {
21
+ unsigned long v;
22
+ for (v = 0; *s != '\0'; s++) { v = *s + 31 * v; }
23
+ return v % HT_BUCKETS;
24
+ }
25
+
26
+ ht_hash_entry_t null_node = { 0, 0, 0 };
27
+
28
+ va_ht_hash_t ht_hash_create(void *base, lmc_error_t *e) {
29
+ va_ht_hash_t va_ht = lmc_valloc(base, sizeof(ht_hash_t));
30
+ if (!va_ht) {
31
+ lmc_handle_error_with_err_string("ht_hash_create", "memory pool full", e);
32
+ return 0;
33
+ }
34
+ memset(base + va_ht, 0, sizeof(ht_hash_t));
35
+ return va_ht;
36
+ }
37
+
38
+ int ht_hash_destroy(void *base, va_ht_hash_t ht) {
39
+ // ignore: Hashes are only deleted by deleting the namespace region
40
+ return 1;
41
+ }
42
+
43
+ ht_hash_entry_t *ht_lookup(void *base, va_ht_hash_t va_ht, const char *key) {
44
+ va_ht_hash_entry_t va_hr;
45
+ ht_hash_entry_t *hr ;
46
+ ht_hash_t *ht = base + va_ht;
47
+ for (va_hr = ht->va_buckets[ht_hash_key(key)];
48
+ va_hr != 0 && hr != NULL; va_hr = hr->va_next) {
49
+ hr = va_hr ? base + va_hr : 0;
50
+ if (hr && (strcmp(key, base + hr->va_key) == 0)) { return hr; }
51
+ }
52
+ return &null_node;
53
+ }
54
+
55
+ char *ht_get(void *base, va_ht_hash_t va_ht, const char *key) {
56
+ size_t va = ht_lookup(base, va_ht, key)->va_value;
57
+ char *r = va ? base + va : 0;
58
+ return r;
59
+ }
60
+
61
+ int ht_set(void *base, va_ht_hash_t va_ht, const char *key,
62
+ const char *value, lmc_error_t *e) {
63
+ ht_hash_t *ht = base + va_ht;
64
+ ht_hash_entry_t *hr = ht_lookup(base, va_ht, key);
65
+ unsigned v;
66
+ if (hr->va_key == 0) {
67
+ va_ht_hash_entry_t va = lmc_valloc(base, sizeof(ht_hash_entry_t));
68
+ hr = va ? base + va : 0;
69
+ if (hr == NULL || (hr->va_key = ht_strdup(base, key)) == 0) {
70
+ lmc_handle_error_with_err_string("ht_set", "memory pool full", e);
71
+ return 0;
72
+ }
73
+ v = ht_hash_key(key);
74
+ hr->va_next = ht->va_buckets[v];
75
+ ht->va_buckets[v] = va;
76
+ } else {
77
+ lmc_free(base, hr->va_value);
78
+ }
79
+ if ((hr->va_value = ht_strdup(base, value)) == 0) {
80
+ lmc_handle_error_with_err_string("ht_set", "memory pool full", e);
81
+ return 0;
82
+ }
83
+ return 1;
84
+ }
85
+
86
+ int ht_delete(void *base, va_ht_hash_t va_ht, const char *key) {
87
+ va_ht_hash_entry_t va_hr;
88
+ ht_hash_entry_t *hr;
89
+ ht_hash_entry_t *p = NULL;
90
+ ht_hash_t *ht = base + va_ht;
91
+ unsigned long k = ht_hash_key(key);
92
+ for (va_hr = ht->va_buckets[k]; va_hr != 0 && hr != NULL;
93
+ va_hr = hr->va_next) {
94
+ hr = va_hr ? base + va_hr : 0;
95
+ if (hr && (strcmp(key, base + hr->va_key) == 0)) {
96
+ // remove previous entry
97
+ if (p) { p->va_next = hr->va_next; }
98
+ else { ht->va_buckets[k] = 0; }
99
+ return 1;
100
+ }
101
+ p = base + hr->va_key;
102
+ }
103
+ return 0;
104
+ }
@@ -0,0 +1,33 @@
1
+ /*
2
+ * Copyright (c) 2009, Sven C. Koehler
3
+ */
4
+
5
+ #ifndef _LMC_HASHTABLE_H_INCLUDED_
6
+ #define _LMC_HASHTABLE_H_INCLUDED_
7
+ #include "lmc_error.h"
8
+
9
+ typedef size_t va_string_t;
10
+ typedef size_t va_ht_hash_entry_t;
11
+
12
+ typedef struct {
13
+ va_ht_hash_entry_t va_next;
14
+ va_string_t va_key;
15
+ va_string_t va_value;
16
+ } ht_hash_entry_t;
17
+
18
+ #define HT_BUCKETS 499
19
+
20
+ typedef size_t va_ht_hash_t;
21
+ typedef struct {
22
+ va_ht_hash_entry_t va_buckets[HT_BUCKETS];
23
+ } ht_hash_t;
24
+
25
+
26
+ va_ht_hash_t ht_hash_create(void *base, lmc_error_t *e);
27
+ int ht_set(void *base, va_ht_hash_t va_ht, const char *key, const char *value,
28
+ lmc_error_t* e);
29
+ ht_hash_entry_t *ht_lookup(void *base, va_ht_hash_t va_ht, const char *key);
30
+ char *ht_get(void *base, va_ht_hash_t ht, const char *key);
31
+ int ht_delete(void *base, va_ht_hash_t va_ht, const char *key);
32
+ int ht_hash_destroy(void *base, va_ht_hash_t ht);
33
+ #endif
data/src/lmc_lock.c ADDED
@@ -0,0 +1,65 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <fcntl.h>
4
+ #include <sys/stat.h>
5
+ #include <errno.h>
6
+ #include <string.h>
7
+ #include <time.h>
8
+ #include "lmc_lock.h"
9
+
10
+ int c_l(lmc_lock_t *l, lmc_error_t *e) {
11
+ if (!l) { strncpy(e->error_str, "Semaphore not initialized", 1023); }
12
+ return l != NULL;
13
+ }
14
+
15
+
16
+
17
+ lmc_lock_t *lmc_lock_init(const char *namespace, int init, lmc_error_t *e) {
18
+ lmc_lock_t *l = malloc(sizeof(lmc_lock_t));
19
+ if (!l) return NULL;
20
+ strncpy((char *)&l->namespace, namespace, 1023);
21
+
22
+ lmc_handle_error((l->sem = sem_open(l->namespace, O_CREAT, 0600, init)) == NULL,
23
+ "sem_open", e);
24
+ if (!l->sem) { free(l); return NULL; }
25
+ return l;
26
+ }
27
+
28
+ int lmc_is_locked(lmc_lock_t* l, lmc_error_t *e) {
29
+ if (!c_l(l, e)) { return 0; }
30
+ if (sem_trywait(l->sem) == -1) {
31
+ return 1;
32
+ } else {
33
+ sem_post(l->sem);
34
+ return 0;
35
+ }
36
+ }
37
+
38
+ int lmc_is_lock_working(lmc_lock_t* l, lmc_error_t *e) {
39
+ if (!c_l(l, e)) { return 0; }
40
+ struct timespec ts;
41
+ clock_gettime(CLOCK_REALTIME, &ts);
42
+ ts.tv_sec += 2;
43
+ if (sem_timedwait(l->sem, &ts) == -1) {
44
+ return 0;
45
+ } else {
46
+ sem_post(l->sem);
47
+ return 1;
48
+ }
49
+ }
50
+
51
+ void lmc_lock_repair(lmc_lock_t *l) {
52
+ int v;
53
+ sem_getvalue(l->sem, &v);
54
+ if (v == 0) { sem_post(l->sem); }
55
+ sem_getvalue(l->sem, &v);
56
+ printf("value after repair: %d\n", v);
57
+ }
58
+
59
+ int lmc_lock_obtain(const char *where, lmc_lock_t* l, lmc_error_t *e) {
60
+ return c_l(l,e) && lmc_handle_error(sem_wait(l->sem) == -1, "sem_wait", e);
61
+ }
62
+
63
+ int lmc_lock_release(const char *where, lmc_lock_t* l, lmc_error_t *e) {
64
+ return c_l(l, e) && lmc_handle_error(sem_post(l->sem) == -1, "sem_post", e);
65
+ }
data/src/lmc_lock.h ADDED
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Copyright (c) 2009, Sven C. Koehler
3
+ */
4
+
5
+ #ifndef _LMC_LOCK_H_
6
+ #define _LMC_LOCK_H_
7
+ #include <semaphore.h>
8
+ #include "lmc_error.h"
9
+
10
+ typedef struct {
11
+ sem_t *sem;
12
+ char namespace[1024];
13
+ } lmc_lock_t;
14
+
15
+ lmc_lock_t *lmc_lock_init(const char *namespace, int init, lmc_error_t *e);
16
+ int lmc_lock_obtain(const char *where, lmc_lock_t* l, lmc_error_t *e);
17
+ int lmc_lock_release(const char *where, lmc_lock_t* l, lmc_error_t *e);
18
+
19
+ int lmc_is_locked(lmc_lock_t* l, lmc_error_t *e);
20
+ int lmc_is_lock_working(lmc_lock_t* l, lmc_error_t *e);
21
+ void lmc_lock_repair(lmc_lock_t *l);
22
+ #endif
data/src/lmc_shm.c ADDED
@@ -0,0 +1,92 @@
1
+ /*
2
+ * Copyright (c) 2009, Sven C. Koehler
3
+ */
4
+
5
+ #include <stdio.h>
6
+ #include <stdlib.h>
7
+ #include <sys/types.h>
8
+ #include <sys/stat.h>
9
+ #include <string.h>
10
+ #include <unistd.h>
11
+ #include <fcntl.h>
12
+ #include <sys/mman.h>
13
+
14
+ #include "lmc_shm.h"
15
+
16
+ #define LMC_SHM_ROOT_PATH "/var/tmp/localmemcache"
17
+
18
+ int lmc_does_file_exist(const char *fn) {
19
+ struct stat st;
20
+ return stat(fn, &st) != -1;
21
+ }
22
+
23
+ void lmc_shm_ensure_root_path() {
24
+ if (!lmc_does_file_exist(LMC_SHM_ROOT_PATH)) {
25
+ mkdir(LMC_SHM_ROOT_PATH, 01777);
26
+ }
27
+ }
28
+
29
+ void lmc_file_path_for_namespace(char *result, const char *ns) {
30
+ snprintf(result, 1023, "%s/%s.lmc", LMC_SHM_ROOT_PATH, ns);
31
+ }
32
+
33
+ int lmc_does_namespace_exist(const char *ns) {
34
+ char fn[1024];
35
+ lmc_file_path_for_namespace((char *)&fn, ns);
36
+ return lmc_does_file_exist(fn);
37
+ }
38
+
39
+ int lmc_clean_namespace(const char *ns, lmc_error_t *e) {
40
+ lmc_shm_ensure_root_path();
41
+ char fn[1024];
42
+ lmc_file_path_for_namespace((char *)&fn, ns);
43
+ if (lmc_does_namespace_exist(ns)) {
44
+ if (!lmc_handle_error(unlink(fn) == -1, "unlink", e)) { return 0; }
45
+ }
46
+ return 1;
47
+ }
48
+
49
+ void lmc_shm_ensure_namespace_file(const char *ns) {
50
+ lmc_shm_ensure_root_path();
51
+ char fn[1024];
52
+ lmc_file_path_for_namespace((char *)&fn, ns);
53
+ if (!lmc_does_namespace_exist(ns)) { close(open(fn, O_CREAT, 0777)); }
54
+ }
55
+
56
+ lmc_shm_t *lmc_shm_create(const char* namespace, size_t size, int use_persistence,
57
+ lmc_error_t *e) {
58
+ lmc_shm_t *mc = calloc(1, sizeof(lmc_shm_t));
59
+ if (!mc) {
60
+ lmc_handle_error_with_err_string("lmc_shm_create", "Out of memory", e);
61
+ return NULL;
62
+ }
63
+ strncpy((char *)&mc->namespace, namespace, 1023);
64
+ mc->use_persistence = 0;
65
+ mc->size = size;
66
+
67
+ lmc_shm_ensure_namespace_file(mc->namespace);
68
+ char fn[1024];
69
+ lmc_file_path_for_namespace((char *)&fn, mc->namespace);
70
+ if (!lmc_handle_error((mc->fd = open(fn, O_RDWR, (mode_t)0777)) == -1,
71
+ "open", e)) goto open_failed;
72
+ if (!lmc_handle_error(lseek(mc->fd, mc->size - 1, SEEK_SET) == -1, "lseek", e))
73
+ goto failed;
74
+ if (!lmc_handle_error(write(mc->fd, "", 1) != 1, "write", e)) goto failed;
75
+ mc->base = mmap(0, mc->size, PROT_READ | PROT_WRITE, MAP_SHARED, mc->fd,
76
+ (off_t)0);
77
+ if (!lmc_handle_error(mc->base == MAP_FAILED, "mmap", e)) goto failed;
78
+ return mc;
79
+
80
+ failed:
81
+ close(mc->fd);
82
+ open_failed:
83
+ free(mc);
84
+ return NULL;
85
+ }
86
+
87
+ int lmc_shm_destroy(lmc_shm_t *mc, lmc_error_t *e) {
88
+ int r = lmc_handle_error(munmap(mc->base, mc->size) == -1, "munmap", e);
89
+ close(mc->fd);
90
+ free(mc);
91
+ return r;
92
+ }
data/src/lmc_shm.h ADDED
@@ -0,0 +1,22 @@
1
+ /*
2
+ * Copyright (c) 2009, Sven C. Koehler
3
+ */
4
+
5
+ #ifndef _LMC_SHM_H_INCLUDED_
6
+ #define _LMC_SHM_H_INCLUDED_
7
+ #include "lmc_error.h"
8
+
9
+ typedef struct {
10
+ int fd;
11
+ void *base;
12
+ size_t size;
13
+ int use_persistence;
14
+ char namespace[1024];
15
+ } lmc_shm_t;
16
+
17
+ lmc_shm_t *lmc_shm_create(const char *namespace, size_t size, int use_persistence,
18
+ lmc_error_t *e);
19
+ int lmc_shm_destroy(lmc_shm_t *mc, lmc_error_t *e);
20
+ int lmc_does_namespace_exist(const char *ns);
21
+ int lmc_clean_namespace(const char *ns, lmc_error_t *e);
22
+ #endif