sophia-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.gitmodules +3 -0
  4. data/Gemfile +6 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +29 -0
  7. data/Rakefile +22 -0
  8. data/ext/extconf.rb +13 -0
  9. data/ext/sophia.c +220 -0
  10. data/lib/sophia-ruby.rb +1 -0
  11. data/lib/sophia/version.rb +3 -0
  12. data/sophia-ruby.gemspec +47 -0
  13. data/test/test_sophia.rb +33 -0
  14. data/vendor/sophia/.gitignore +18 -0
  15. data/vendor/sophia/COPYRIGHT +29 -0
  16. data/vendor/sophia/README +5 -0
  17. data/vendor/sophia/db/a.h +58 -0
  18. data/vendor/sophia/db/cat.c +195 -0
  19. data/vendor/sophia/db/cat.h +32 -0
  20. data/vendor/sophia/db/core.h +129 -0
  21. data/vendor/sophia/db/crc.c +343 -0
  22. data/vendor/sophia/db/crc.h +14 -0
  23. data/vendor/sophia/db/cursor.c +551 -0
  24. data/vendor/sophia/db/cursor.h +47 -0
  25. data/vendor/sophia/db/e.c +49 -0
  26. data/vendor/sophia/db/e.h +49 -0
  27. data/vendor/sophia/db/file.c +355 -0
  28. data/vendor/sophia/db/file.h +106 -0
  29. data/vendor/sophia/db/gc.c +71 -0
  30. data/vendor/sophia/db/gc.h +14 -0
  31. data/vendor/sophia/db/i.c +368 -0
  32. data/vendor/sophia/db/i.h +155 -0
  33. data/vendor/sophia/db/list.h +91 -0
  34. data/vendor/sophia/db/lock.h +77 -0
  35. data/vendor/sophia/db/macro.h +20 -0
  36. data/vendor/sophia/db/makefile +44 -0
  37. data/vendor/sophia/db/merge.c +662 -0
  38. data/vendor/sophia/db/merge.h +14 -0
  39. data/vendor/sophia/db/meta.h +87 -0
  40. data/vendor/sophia/db/recover.c +433 -0
  41. data/vendor/sophia/db/recover.h +14 -0
  42. data/vendor/sophia/db/ref.h +111 -0
  43. data/vendor/sophia/db/rep.c +128 -0
  44. data/vendor/sophia/db/rep.h +120 -0
  45. data/vendor/sophia/db/sophia.h +84 -0
  46. data/vendor/sophia/db/sp.c +626 -0
  47. data/vendor/sophia/db/sp.h +50 -0
  48. data/vendor/sophia/db/task.h +70 -0
  49. data/vendor/sophia/db/track.h +99 -0
  50. data/vendor/sophia/db/util.c +105 -0
  51. data/vendor/sophia/db/util.h +25 -0
  52. data/vendor/sophia/makefile +7 -0
  53. data/vendor/sophia/sophia.gyp +30 -0
  54. data/vendor/sophia/test/common.c +870 -0
  55. data/vendor/sophia/test/crash.c +492 -0
  56. data/vendor/sophia/test/i.c +403 -0
  57. data/vendor/sophia/test/limit.c +65 -0
  58. data/vendor/sophia/test/makefile +30 -0
  59. data/vendor/sophia/test/merge.c +890 -0
  60. data/vendor/sophia/test/recover.c +1550 -0
  61. data/vendor/sophia/test/test.h +66 -0
  62. metadata +134 -0
@@ -0,0 +1,29 @@
1
+
2
+ Copyright (C) 2013 Dmitry Simonenko (pmwkaa@gmail.com)
3
+
4
+ Redistribution and use in source and binary forms, with or
5
+ without modification, are permitted provided that the following
6
+ conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above
9
+ copyright notice, this list of conditions and the
10
+ following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above
13
+ copyright notice, this list of conditions and the following
14
+ disclaimer in the documentation and/or other materials
15
+ provided with the distribution.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY AUTHORS ``AS IS'' AND
18
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21
+ AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
+ SUCH DAMAGE.
@@ -0,0 +1,5 @@
1
+
2
+ sophia - is a modern embeddable key-value database
3
+ designed for a high load.
4
+
5
+ http://sphia.org
@@ -0,0 +1,58 @@
1
+ #ifndef SP_A_H_
2
+ #define SP_A_H_
3
+
4
+ /*
5
+ * sophia database
6
+ * sphia.org
7
+ *
8
+ * Copyright (c) Dmitry Simonenko
9
+ * BSD License
10
+ */
11
+
12
+ typedef struct spa spa;
13
+
14
+ struct spa {
15
+ spallocf alloc;
16
+ void *arg;
17
+ };
18
+
19
+ static inline void
20
+ sp_allocinit(spa *a, spallocf f, void *arg) {
21
+ a->alloc = f;
22
+ a->arg = arg;
23
+ }
24
+
25
+ static inline void*
26
+ sp_allocstd(void *ptr, size_t size, void *arg spunused) {
27
+ if (splikely(size > 0)) {
28
+ if (ptr != NULL)
29
+ return realloc(ptr, size);
30
+ return malloc(size);
31
+ }
32
+ assert(ptr != NULL);
33
+ free(ptr);
34
+ return NULL;
35
+ }
36
+
37
+ static inline void *sp_realloc(spa *a, void *ptr, size_t size) {
38
+ return a->alloc(ptr, size, a->arg);
39
+ }
40
+
41
+ static inline void *sp_malloc(spa *a, size_t size) {
42
+ return a->alloc(NULL, size, a->arg);
43
+ }
44
+
45
+ static inline char *sp_strdup(spa *a, char *str) {
46
+ int sz = strlen(str) + 1;
47
+ char *s = a->alloc(NULL, sz, a->arg);
48
+ if (spunlikely(s == NULL))
49
+ return NULL;
50
+ memcpy(s, str, sz);
51
+ return s;
52
+ }
53
+
54
+ static inline void sp_free(spa *a, void *ptr) {
55
+ a->alloc(ptr, 0, a->arg);
56
+ }
57
+
58
+ #endif
@@ -0,0 +1,195 @@
1
+
2
+ /*
3
+ * sophia database
4
+ * sphia.org
5
+ *
6
+ * Copyright (c) Dmitry Simonenko
7
+ * BSD License
8
+ */
9
+
10
+ #include <sp.h>
11
+
12
+ static inline int sp_catensure(spcat *c) {
13
+ if ((c->count + 1) < c->top)
14
+ return 0;
15
+ c->top *= 2;
16
+ c->i = realloc(c->i, c->top * sizeof(sppage*));
17
+ if (c->i == NULL)
18
+ return -1;
19
+ return 0;
20
+ }
21
+
22
+ int sp_catinit(spcat *c, spa *a, int top, spcmpf cmp, void *cmparg) {
23
+ c->a = a;
24
+ c->cmp = cmp;
25
+ c->cmparg = cmparg;
26
+ c->count = 0;
27
+ c->top = top;
28
+ c->i = sp_malloc(a, sizeof(sppage*) * top);
29
+ if (spunlikely(c->i == NULL))
30
+ return -1;
31
+ return 0;
32
+ }
33
+
34
+ void sp_catfree(spcat *c) {
35
+ uint32_t p = 0;
36
+ while (p < c->count) {
37
+ sp_free(c->a, c->i[p]->min);
38
+ sp_free(c->a, c->i[p]->max);
39
+ sp_free(c->a, c->i[p]);
40
+ p++;
41
+ }
42
+ sp_free(c->a, c->i);
43
+ }
44
+
45
+ static inline int
46
+ cmppage(spcat *c, sppage *p, sppage *v) {
47
+ int l = c->cmp(p->min->key,
48
+ p->min->size,
49
+ v->min->key,
50
+ v->min->size, c->cmparg);
51
+ assert(l == c->cmp(p->max->key,
52
+ p->max->size,
53
+ v->max->key,
54
+ v->max->size, c->cmparg));
55
+ return l;
56
+ }
57
+
58
+ static inline sppage*
59
+ sp_catsearch(spcat *c, sppage *v, uint32_t *index) {
60
+ int min = 0;
61
+ int max = c->count - 1;
62
+ while (max >= min) {
63
+ int mid = min + ((max - min) >> 1);
64
+ switch (cmppage(c, c->i[mid], v)) {
65
+ case -1: min = mid + 1;
66
+ continue;
67
+ case 1: max = mid - 1;
68
+ continue;
69
+ default:
70
+ *index = mid;
71
+ return c->i[mid];
72
+ }
73
+ }
74
+ *index = min;
75
+ return NULL;
76
+ }
77
+
78
+ int sp_catset(spcat *c, sppage *n, sppage **o)
79
+ {
80
+ uint32_t i;
81
+ sppage *p = sp_catsearch(c, n, &i);
82
+ if (p) {
83
+ /* replace */
84
+ *o = c->i[i];
85
+ c->i[i] = p;
86
+ return 0;
87
+ }
88
+ /* insert */
89
+ int rc = sp_catensure(c);
90
+ if (spunlikely(rc == -1))
91
+ return -1;
92
+ /* split page index and insert new page */
93
+ memmove(&c->i[i + 1], &c->i[i], sizeof(sppage*) * (c->count - i));
94
+ c->i[i] = n;
95
+ c->count++;
96
+ *o = NULL;
97
+ return 0;
98
+ }
99
+
100
+ int sp_catdel(spcat *c, uint32_t idx)
101
+ {
102
+ assert(idx < c->count);
103
+ if (splikely(idx != (uint32_t)(c->count-1)))
104
+ memmove(&c->i[idx], &c->i[idx + 1],
105
+ sizeof(sppage*) * (c->count - idx - 1));
106
+ c->count--;
107
+ return 0;
108
+ }
109
+
110
+ static inline int
111
+ cmpkey(spcat *c, sppage *p, void *rkey, int size)
112
+ {
113
+ register int l =
114
+ c->cmp(p->min->key, p->min->size, rkey, size, c->cmparg);
115
+ register int r =
116
+ c->cmp(p->max->key, p->max->size, rkey, size, c->cmparg);
117
+ /* inside page range */
118
+ if (l <= 0 && r >= 0)
119
+ return 0;
120
+ /* key > page */
121
+ if (l == -1)
122
+ return -1;
123
+ /* key < page */
124
+ assert(r == 1);
125
+ return 1;
126
+ }
127
+
128
+ sppage*
129
+ sp_catfind(spcat *c, char *rkey, int size, uint32_t *index)
130
+ {
131
+ register int min = 0;
132
+ register int max = c->count - 1;
133
+ while (max >= min) {
134
+ register int mid = min + ((max - min) >> 1);
135
+ switch (cmpkey(c, c->i[mid], rkey, size)) {
136
+ case -1: min = mid + 1;
137
+ continue;
138
+ case 1: max = mid - 1;
139
+ continue;
140
+ default: *index = mid;
141
+ return c->i[mid];
142
+ }
143
+ }
144
+ *index = min;
145
+ return NULL;
146
+ }
147
+
148
+ sppage *sp_catroute(spcat *c, char *rkey, int size, uint32_t *idx)
149
+ {
150
+ if (spunlikely(c->count == 1))
151
+ return c->i[0];
152
+ uint32_t i;
153
+ sppage *p = sp_catfind(c, rkey, size, &i);
154
+ if (splikely(p)) {
155
+ *idx = i;
156
+ return p;
157
+ }
158
+ if (spunlikely(i >= c->count))
159
+ i = c->count - 1;
160
+
161
+ if (i > 0 && c->cmp(c->i[i]->min->key, c->i[i]->min->size,
162
+ rkey,
163
+ size, c->cmparg) == 1) {
164
+ i = i - 1;
165
+ }
166
+ if (idx)
167
+ *idx = i;
168
+ return c->i[i];
169
+ }
170
+
171
+ int sp_catown(spcat *c, uint32_t idx, spv *v)
172
+ {
173
+ register sppage *p = c->i[idx];
174
+ /* equal or equal min or equal max */
175
+ switch (cmpkey(c, p, v->key, v->size)) {
176
+ case 0:
177
+ return 1;
178
+ case -1: /* key > page */
179
+ /* key > max */
180
+ if (idx == c->count-1)
181
+ return 1;
182
+ break;
183
+ case 1: /* key < page */
184
+ /* key < min */
185
+ if (idx == 0)
186
+ return 1;
187
+ break;
188
+ }
189
+ /* key > page && key < page+1.min */
190
+ if (c->cmp(v->key, v->size,
191
+ c->i[idx + 1]->min->key,
192
+ c->i[idx + 1]->min->size, c->cmparg) == -1)
193
+ return 1;
194
+ return 0;
195
+ }
@@ -0,0 +1,32 @@
1
+ #ifndef SP_CAT_H_
2
+ #define SP_CAT_H_
3
+
4
+ /*
5
+ * sophia database
6
+ * sphia.org
7
+ *
8
+ * Copyright (c) Dmitry Simonenko
9
+ * BSD License
10
+ */
11
+
12
+ typedef struct spcat spcat;
13
+
14
+ struct spcat {
15
+ spa *a;
16
+ sppage **i;
17
+ uint32_t count;
18
+ uint32_t top;
19
+ spcmpf cmp;
20
+ void *cmparg;
21
+ };
22
+
23
+ int sp_catinit(spcat*, spa*, int, spcmpf, void*);
24
+ void sp_catfree(spcat*);
25
+ int sp_catset(spcat*, sppage*, sppage**);
26
+ int sp_catget(spcat*, uint64_t);
27
+ int sp_catdel(spcat*, uint32_t);
28
+ sppage *sp_catfind(spcat*, char*, int, uint32_t*);
29
+ sppage *sp_catroute(spcat*, char*, int, uint32_t*);
30
+ int sp_catown(spcat*, uint32_t, spv*);
31
+
32
+ #endif
@@ -0,0 +1,129 @@
1
+ #ifndef SP_CORE_H_
2
+ #define SP_CORE_H_
3
+
4
+ /*
5
+ * sophia database
6
+ * sphia.org
7
+ *
8
+ * Copyright (c) Dmitry Simonenko
9
+ * BSD License
10
+ */
11
+
12
+ #define SP_VERSION_MAJOR 1
13
+ #define SP_VERSION_MINOR 1
14
+
15
+ typedef struct sp sp;
16
+ typedef struct spenv spenv;
17
+
18
+ enum spmagic {
19
+ SPMCUR = 0x15481936L,
20
+ SPMENV = 0x06154834L,
21
+ SPMDB = 0x00fec0feL,
22
+ SPMNONE = 0L
23
+ };
24
+
25
+ typedef enum spmagic spmagic;
26
+
27
+ struct spenv {
28
+ spmagic m;
29
+ spe e;
30
+ int inuse;
31
+ spallocf alloc;
32
+ void *allocarg;
33
+ spcmpf cmp;
34
+ void *cmparg;
35
+ uint32_t flags;
36
+ char *dir;
37
+ int merge;
38
+ uint32_t mergewm;
39
+ uint32_t page;
40
+ uint32_t dbnewsize;
41
+ float dbgrow;
42
+ int gc;
43
+ float gcfactor;
44
+ };
45
+
46
+ struct sp {
47
+ spmagic m;
48
+ spenv *e;
49
+ spa a;
50
+ sprep rep;
51
+ spi *i, i0, i1;
52
+ int iskip; /* skip second index during read */
53
+ uint64_t psn; /* page sequence number */
54
+ spcat s;
55
+ volatile int stop;
56
+ sptask merger;
57
+ sprefset refs; /* pre allocated key buffer (page merge) */
58
+ int lockc; /* incremental cursor lock */
59
+ spspinlock lockr; /* repository lock */
60
+ spspinlock locks; /* space lock */
61
+ spspinlock locki; /* index lock */
62
+ };
63
+
64
+ int sp_rotate(sp*);
65
+
66
+ static inline int sp_active(sp *s) {
67
+ return !s->stop;
68
+ }
69
+
70
+ static inline int
71
+ sp_e(sp *s, int type, ...) {
72
+ va_list args;
73
+ va_start(args, type);
74
+ sp_ve(&s->e->e, type, args);
75
+ va_end(args);
76
+ return -1;
77
+ }
78
+
79
+ static inline int
80
+ sp_ee(spenv *e, int type, ...) {
81
+ va_list args;
82
+ va_start(args, type);
83
+ sp_ve(&e->e, type, args);
84
+ va_end(args);
85
+ return -1;
86
+ }
87
+
88
+ static inline void
89
+ sp_glock(sp *s) {
90
+ if (s->lockc > 0)
91
+ return;
92
+ sp_lock(&s->lockr);
93
+ sp_replockall(&s->rep);
94
+ sp_lock(&s->locki);
95
+ sp_lock(&s->locks);
96
+ s->lockc++;
97
+ }
98
+
99
+ static inline void
100
+ sp_gunlock(sp *s) {
101
+ s->lockc--;
102
+ if (s->lockc > 0)
103
+ return;
104
+ sp_unlock(&s->locks);
105
+ sp_unlock(&s->locki);
106
+ sp_repunlockall(&s->rep);
107
+ sp_unlock(&s->lockr);
108
+ }
109
+
110
+ static inline void
111
+ sp_iskipset(sp *s, int v) {
112
+ sp_lock(&s->locki);
113
+ s->iskip = v;
114
+ sp_unlock(&s->locki);
115
+ }
116
+
117
+ static inline spi*
118
+ sp_ipair(sp *s) {
119
+ return (s->i == &s->i0 ? &s->i1 : &s->i0);
120
+ }
121
+
122
+ static inline spi*
123
+ sp_iswap(sp *s) {
124
+ spi *old = s->i;
125
+ s->i = sp_ipair(s);
126
+ return old;
127
+ }
128
+
129
+ #endif