sophia-ruby 0.0.1

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 (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