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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.gitmodules +3 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +22 -0
- data/ext/extconf.rb +13 -0
- data/ext/sophia.c +220 -0
- data/lib/sophia-ruby.rb +1 -0
- data/lib/sophia/version.rb +3 -0
- data/sophia-ruby.gemspec +47 -0
- data/test/test_sophia.rb +33 -0
- data/vendor/sophia/.gitignore +18 -0
- data/vendor/sophia/COPYRIGHT +29 -0
- data/vendor/sophia/README +5 -0
- data/vendor/sophia/db/a.h +58 -0
- data/vendor/sophia/db/cat.c +195 -0
- data/vendor/sophia/db/cat.h +32 -0
- data/vendor/sophia/db/core.h +129 -0
- data/vendor/sophia/db/crc.c +343 -0
- data/vendor/sophia/db/crc.h +14 -0
- data/vendor/sophia/db/cursor.c +551 -0
- data/vendor/sophia/db/cursor.h +47 -0
- data/vendor/sophia/db/e.c +49 -0
- data/vendor/sophia/db/e.h +49 -0
- data/vendor/sophia/db/file.c +355 -0
- data/vendor/sophia/db/file.h +106 -0
- data/vendor/sophia/db/gc.c +71 -0
- data/vendor/sophia/db/gc.h +14 -0
- data/vendor/sophia/db/i.c +368 -0
- data/vendor/sophia/db/i.h +155 -0
- data/vendor/sophia/db/list.h +91 -0
- data/vendor/sophia/db/lock.h +77 -0
- data/vendor/sophia/db/macro.h +20 -0
- data/vendor/sophia/db/makefile +44 -0
- data/vendor/sophia/db/merge.c +662 -0
- data/vendor/sophia/db/merge.h +14 -0
- data/vendor/sophia/db/meta.h +87 -0
- data/vendor/sophia/db/recover.c +433 -0
- data/vendor/sophia/db/recover.h +14 -0
- data/vendor/sophia/db/ref.h +111 -0
- data/vendor/sophia/db/rep.c +128 -0
- data/vendor/sophia/db/rep.h +120 -0
- data/vendor/sophia/db/sophia.h +84 -0
- data/vendor/sophia/db/sp.c +626 -0
- data/vendor/sophia/db/sp.h +50 -0
- data/vendor/sophia/db/task.h +70 -0
- data/vendor/sophia/db/track.h +99 -0
- data/vendor/sophia/db/util.c +105 -0
- data/vendor/sophia/db/util.h +25 -0
- data/vendor/sophia/makefile +7 -0
- data/vendor/sophia/sophia.gyp +30 -0
- data/vendor/sophia/test/common.c +870 -0
- data/vendor/sophia/test/crash.c +492 -0
- data/vendor/sophia/test/i.c +403 -0
- data/vendor/sophia/test/limit.c +65 -0
- data/vendor/sophia/test/makefile +30 -0
- data/vendor/sophia/test/merge.c +890 -0
- data/vendor/sophia/test/recover.c +1550 -0
- data/vendor/sophia/test/test.h +66 -0
- metadata +134 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
#ifndef SP_KEY_H_
|
2
|
+
#define SP_KEY_H_
|
3
|
+
|
4
|
+
/*
|
5
|
+
* sophia database
|
6
|
+
* sphia.org
|
7
|
+
*
|
8
|
+
* Copyright (c) Dmitry Simonenko
|
9
|
+
* BSD License
|
10
|
+
*/
|
11
|
+
|
12
|
+
typedef struct spref spref;
|
13
|
+
typedef struct sprefset sprefset;
|
14
|
+
|
15
|
+
#define SPREFNONE 0
|
16
|
+
#define SPREFD 1
|
17
|
+
#define SPREFM 2
|
18
|
+
|
19
|
+
struct spref {
|
20
|
+
uint8_t type;
|
21
|
+
union {
|
22
|
+
spvh *vh;
|
23
|
+
spv *v;
|
24
|
+
} v;
|
25
|
+
} sppacked;
|
26
|
+
|
27
|
+
struct sprefset {
|
28
|
+
spref *r;
|
29
|
+
int used;
|
30
|
+
int max;
|
31
|
+
};
|
32
|
+
|
33
|
+
static inline char*
|
34
|
+
sp_refk(spref *r) {
|
35
|
+
switch (r->type) {
|
36
|
+
case SPREFD: return r->v.vh->key;
|
37
|
+
case SPREFM: return r->v.v->key;
|
38
|
+
}
|
39
|
+
return NULL;
|
40
|
+
}
|
41
|
+
|
42
|
+
static inline size_t
|
43
|
+
sp_refksize(spref *r) {
|
44
|
+
switch (r->type) {
|
45
|
+
case SPREFD: return r->v.vh->size;
|
46
|
+
case SPREFM: return r->v.v->size;
|
47
|
+
}
|
48
|
+
return 0;
|
49
|
+
}
|
50
|
+
|
51
|
+
static inline char*
|
52
|
+
sp_refv(spref *r, char *p) {
|
53
|
+
switch (r->type) {
|
54
|
+
case SPREFD: return p + r->v.vh->voffset;
|
55
|
+
case SPREFM: return sp_vv(r->v.v);
|
56
|
+
}
|
57
|
+
return NULL;
|
58
|
+
}
|
59
|
+
|
60
|
+
static inline size_t
|
61
|
+
sp_refvsize(spref *r) {
|
62
|
+
switch (r->type) {
|
63
|
+
case SPREFD: return r->v.vh->vsize;
|
64
|
+
case SPREFM: return sp_vvsize(r->v.v);
|
65
|
+
}
|
66
|
+
return 0;
|
67
|
+
}
|
68
|
+
|
69
|
+
static inline int
|
70
|
+
sp_refisdel(spref *r) {
|
71
|
+
register int flags = 0;
|
72
|
+
switch (r->type) {
|
73
|
+
case SPREFM: flags = r->v.v->flags;
|
74
|
+
break;
|
75
|
+
case SPREFD: flags = r->v.vh->flags;
|
76
|
+
break;
|
77
|
+
}
|
78
|
+
return (flags & SPDEL? 1: 0);
|
79
|
+
}
|
80
|
+
|
81
|
+
static inline int
|
82
|
+
sp_refsetinit(sprefset *s, spa *a, int count) {
|
83
|
+
s->r = sp_malloc(a, count * sizeof(spref));
|
84
|
+
if (spunlikely(s->r == NULL))
|
85
|
+
return -1;
|
86
|
+
s->used = 0;
|
87
|
+
s->max = count;
|
88
|
+
return 0;
|
89
|
+
}
|
90
|
+
|
91
|
+
static inline void
|
92
|
+
sp_refsetfree(sprefset *s, spa *a) {
|
93
|
+
if (s->r) {
|
94
|
+
sp_free(a, s->r);
|
95
|
+
s->r = NULL;
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
static inline void
|
100
|
+
sp_refsetadd(sprefset *s, spref *r) {
|
101
|
+
assert(s->used < s->max);
|
102
|
+
s->r[s->used] = *r;
|
103
|
+
s->used++;
|
104
|
+
}
|
105
|
+
|
106
|
+
static inline void
|
107
|
+
sp_refsetreset(sprefset *s) {
|
108
|
+
s->used = 0;
|
109
|
+
}
|
110
|
+
|
111
|
+
#endif
|
@@ -0,0 +1,128 @@
|
|
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
|
+
void sp_repinit(sprep *r, spa *a) {
|
13
|
+
sp_listinit(&r->l);
|
14
|
+
r->a = a;
|
15
|
+
r->n = 0;
|
16
|
+
r->ndb = 0;
|
17
|
+
r->nxfer = 0;
|
18
|
+
r->epoch = 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
void sp_repfree(sprep *r) {
|
22
|
+
splist *i, *n;
|
23
|
+
sp_listforeach_safe(&r->l, i, n) {
|
24
|
+
spepoch *e = spcast(i, spepoch, link);
|
25
|
+
sp_lockfree(&e->lock);
|
26
|
+
sp_free(r->a, e);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
static inline int sp_repcmp(const void *p1, const void *p2) {
|
31
|
+
register const spepoch *a = *(spepoch**)p1;
|
32
|
+
register const spepoch *b = *(spepoch**)p2;
|
33
|
+
assert(a->epoch != b->epoch);
|
34
|
+
return (a->epoch > b->epoch)? 1: -1;
|
35
|
+
}
|
36
|
+
|
37
|
+
int sp_repprepare(sprep *r) {
|
38
|
+
spepoch **a = sp_malloc(r->a, sizeof(spepoch*) * r->n);
|
39
|
+
if (spunlikely(a == NULL))
|
40
|
+
return -1;
|
41
|
+
uint32_t epoch = 0;
|
42
|
+
int j = 0;
|
43
|
+
splist *i;
|
44
|
+
sp_listforeach(&r->l, i) {
|
45
|
+
a[j] = spcast(i, spepoch, link);
|
46
|
+
if (a[j]->epoch > epoch)
|
47
|
+
epoch = a[j]->epoch;
|
48
|
+
j++;
|
49
|
+
}
|
50
|
+
qsort(a, r->n, sizeof(spepoch*), sp_repcmp);
|
51
|
+
sp_listinit(&r->l);
|
52
|
+
j = 0;
|
53
|
+
while (j < r->n) {
|
54
|
+
sp_listinit(&a[j]->link);
|
55
|
+
sp_listappend(&r->l, &a[j]->link);
|
56
|
+
j++;
|
57
|
+
}
|
58
|
+
sp_free(r->a, a);
|
59
|
+
r->epoch = epoch;
|
60
|
+
return 0;
|
61
|
+
}
|
62
|
+
|
63
|
+
spepoch *sp_repmatch(sprep *r, uint32_t epoch) {
|
64
|
+
splist *i;
|
65
|
+
sp_listforeach(&r->l, i) {
|
66
|
+
spepoch *e = spcast(i, spepoch, link);
|
67
|
+
if (e->epoch == epoch)
|
68
|
+
return e;
|
69
|
+
}
|
70
|
+
return NULL;
|
71
|
+
}
|
72
|
+
|
73
|
+
spepoch *sp_repalloc(sprep *r, uint32_t epoch)
|
74
|
+
{
|
75
|
+
spepoch *e = sp_malloc(r->a, sizeof(spepoch));
|
76
|
+
if (spunlikely(e == NULL))
|
77
|
+
return NULL;
|
78
|
+
memset(e, 0, sizeof(spepoch));
|
79
|
+
e->recover = SPRNONE;
|
80
|
+
e->epoch = epoch;
|
81
|
+
e->type = SPUNDEF;
|
82
|
+
e->nupdate = 0;
|
83
|
+
e->n = 0;
|
84
|
+
e->ngc = 0;
|
85
|
+
sp_lockinit(&e->lock);
|
86
|
+
sp_fileinit(&e->db, r->a);
|
87
|
+
sp_fileinit(&e->log, r->a);
|
88
|
+
sp_listinit(&e->pages);
|
89
|
+
sp_listinit(&e->link);
|
90
|
+
return e;
|
91
|
+
}
|
92
|
+
|
93
|
+
void sp_repattach(sprep *r, spepoch *e) {
|
94
|
+
sp_listappend(&r->l, &e->link);
|
95
|
+
r->n++;
|
96
|
+
}
|
97
|
+
|
98
|
+
void sp_repdetach(sprep *r, spepoch *e) {
|
99
|
+
sp_listunlink(&e->link);
|
100
|
+
r->n--;
|
101
|
+
sp_repset(r, e, SPUNDEF);
|
102
|
+
}
|
103
|
+
|
104
|
+
void sp_repset(sprep *r, spepoch *e, spepochtype t) {
|
105
|
+
switch (t) {
|
106
|
+
case SPUNDEF:
|
107
|
+
if (e->type == SPXFER)
|
108
|
+
r->nxfer--;
|
109
|
+
else
|
110
|
+
if (e->type == SPDB)
|
111
|
+
r->ndb--;
|
112
|
+
break;
|
113
|
+
case SPLIVE:
|
114
|
+
assert(e->type == SPUNDEF);
|
115
|
+
break;
|
116
|
+
case SPXFER:
|
117
|
+
assert(e->type == SPLIVE || e->type == SPUNDEF);
|
118
|
+
r->nxfer++;
|
119
|
+
break;
|
120
|
+
case SPDB:
|
121
|
+
assert(e->type == SPXFER || e->type == SPUNDEF);
|
122
|
+
if (e->type == SPXFER)
|
123
|
+
r->nxfer--;
|
124
|
+
r->ndb++;
|
125
|
+
break;
|
126
|
+
}
|
127
|
+
e->type = t;
|
128
|
+
}
|
@@ -0,0 +1,120 @@
|
|
1
|
+
#ifndef SP_REP_H_
|
2
|
+
#define SP_REP_H_
|
3
|
+
|
4
|
+
/*
|
5
|
+
* sophia database
|
6
|
+
* sphia.org
|
7
|
+
*
|
8
|
+
* Copyright (c) Dmitry Simonenko
|
9
|
+
* BSD License
|
10
|
+
*/
|
11
|
+
|
12
|
+
typedef struct spepoch spepoch;
|
13
|
+
typedef struct sprep sprep;
|
14
|
+
|
15
|
+
enum spepochtype {
|
16
|
+
SPUNDEF,
|
17
|
+
SPLIVE,
|
18
|
+
SPXFER,
|
19
|
+
SPDB
|
20
|
+
};
|
21
|
+
|
22
|
+
typedef enum spepochtype spepochtype;
|
23
|
+
|
24
|
+
#define SPRNONE 0
|
25
|
+
#define SPRDB 1
|
26
|
+
#define SPRDBI 2
|
27
|
+
#define SPRLOG 4
|
28
|
+
#define SPRLOGI 8
|
29
|
+
|
30
|
+
struct spepoch {
|
31
|
+
uint32_t epoch;
|
32
|
+
uint32_t n; /* count of pages */
|
33
|
+
uint32_t ngc; /* count of gc pages */
|
34
|
+
uint32_t nupdate; /* count of updated keys */
|
35
|
+
spepochtype type; /* epoch life-cycle state */
|
36
|
+
uint32_t recover; /* recover status */
|
37
|
+
spfile log, db;
|
38
|
+
spspinlock lock; /* db lock */
|
39
|
+
splist pages; /* list of associated pages */
|
40
|
+
splist link;
|
41
|
+
};
|
42
|
+
|
43
|
+
struct sprep {
|
44
|
+
spa *a;
|
45
|
+
uint32_t epoch;
|
46
|
+
splist l;
|
47
|
+
int n;
|
48
|
+
int ndb;
|
49
|
+
int nxfer;
|
50
|
+
};
|
51
|
+
|
52
|
+
void sp_repinit(sprep*, spa*);
|
53
|
+
void sp_repfree(sprep*);
|
54
|
+
int sp_repprepare(sprep*);
|
55
|
+
spepoch *sp_repmatch(sprep *r, uint32_t epoch);
|
56
|
+
spepoch *sp_repalloc(sprep*, uint32_t);
|
57
|
+
void sp_repattach(sprep*, spepoch*);
|
58
|
+
void sp_repdetach(sprep*, spepoch*);
|
59
|
+
void sp_repset(sprep*, spepoch*, spepochtype);
|
60
|
+
|
61
|
+
static inline uint32_t
|
62
|
+
sp_repepoch(sprep *r) {
|
63
|
+
return r->epoch;
|
64
|
+
}
|
65
|
+
|
66
|
+
static inline void
|
67
|
+
sp_repepochincrement(sprep *r) {
|
68
|
+
r->epoch++;
|
69
|
+
}
|
70
|
+
|
71
|
+
static inline void
|
72
|
+
sp_replockall(sprep *r) {
|
73
|
+
register splist *i;
|
74
|
+
sp_listforeach(&r->l, i) {
|
75
|
+
register spepoch *e = spcast(i, spepoch, link);
|
76
|
+
sp_lock(&e->lock);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
static inline void
|
81
|
+
sp_repunlockall(sprep *r) {
|
82
|
+
register splist *i;
|
83
|
+
sp_listforeach(&r->l, i) {
|
84
|
+
register spepoch *e = spcast(i, spepoch, link);
|
85
|
+
sp_unlock(&e->lock);
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
static inline spepoch*
|
90
|
+
sp_replive(sprep *r) {
|
91
|
+
register spepoch *e = spcast(r->l.prev, spepoch, link);
|
92
|
+
assert(e->type == SPLIVE);
|
93
|
+
return e;
|
94
|
+
}
|
95
|
+
|
96
|
+
static inline spepoch*
|
97
|
+
sp_repxfer(sprep *r) {
|
98
|
+
register splist *i;
|
99
|
+
sp_listforeach(&r->l, i) {
|
100
|
+
register spepoch *s = spcast(i, spepoch, link);
|
101
|
+
if (s->type == SPXFER)
|
102
|
+
return s;
|
103
|
+
}
|
104
|
+
return NULL;
|
105
|
+
}
|
106
|
+
|
107
|
+
static inline spepoch*
|
108
|
+
sp_repgc(sprep *r, float factor) {
|
109
|
+
register splist *i;
|
110
|
+
sp_listforeach(&r->l, i) {
|
111
|
+
register spepoch *s = spcast(i, spepoch, link);
|
112
|
+
if (s->type != SPDB)
|
113
|
+
continue;
|
114
|
+
if (s->ngc > (s->n * factor))
|
115
|
+
return s;
|
116
|
+
}
|
117
|
+
return NULL;
|
118
|
+
}
|
119
|
+
|
120
|
+
#endif
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#ifndef SOPHIA_H_
|
2
|
+
#define SOPHIA_H_
|
3
|
+
|
4
|
+
/*
|
5
|
+
* sophia database
|
6
|
+
* sphia.org
|
7
|
+
*
|
8
|
+
* Copyright (c) Dmitry Simonenko
|
9
|
+
* BSD License
|
10
|
+
*/
|
11
|
+
|
12
|
+
#ifdef __cplusplus
|
13
|
+
extern "C" {
|
14
|
+
#endif
|
15
|
+
|
16
|
+
#include <stdlib.h>
|
17
|
+
#include <stdint.h>
|
18
|
+
|
19
|
+
typedef void *(*spallocf)(void *ptr, size_t size, void *arg);
|
20
|
+
typedef int (*spcmpf)(char *a, size_t asz, char *b, size_t bsz, void *arg);
|
21
|
+
|
22
|
+
typedef enum {
|
23
|
+
/* env related */
|
24
|
+
SPDIR, /* uint32_t, char* */
|
25
|
+
SPALLOC, /* spallocf, void* */
|
26
|
+
SPCMP, /* spcmpf, void* */
|
27
|
+
SPPAGE, /* uint32_t */
|
28
|
+
SPGC, /* int */
|
29
|
+
SPGCF, /* double */
|
30
|
+
SPGROW, /* uint32_t, double */
|
31
|
+
SPMERGE, /* int */
|
32
|
+
SPMERGEWM, /* uint32_t */
|
33
|
+
/* db related */
|
34
|
+
SPMERGEFORCE,
|
35
|
+
/* unrelated */
|
36
|
+
SPVERSION /* uint32_t*, uint32_t* */
|
37
|
+
} spopt;
|
38
|
+
|
39
|
+
enum {
|
40
|
+
SPO_RDONLY = 1,
|
41
|
+
SPO_RDWR = 2,
|
42
|
+
SPO_CREAT = 4,
|
43
|
+
SPO_SYNC = 8
|
44
|
+
};
|
45
|
+
|
46
|
+
typedef enum {
|
47
|
+
SPGT,
|
48
|
+
SPGTE,
|
49
|
+
SPLT,
|
50
|
+
SPLTE
|
51
|
+
} sporder;
|
52
|
+
|
53
|
+
typedef struct {
|
54
|
+
uint32_t epoch;
|
55
|
+
uint64_t psn;
|
56
|
+
uint32_t repn;
|
57
|
+
uint32_t repndb;
|
58
|
+
uint32_t repnxfer;
|
59
|
+
uint32_t catn;
|
60
|
+
uint32_t indexn;
|
61
|
+
uint32_t indexpages;
|
62
|
+
} spstat;
|
63
|
+
|
64
|
+
void *sp_env(void);
|
65
|
+
void *sp_open(void *env);
|
66
|
+
int sp_ctl(void*, spopt, ...);
|
67
|
+
int sp_destroy(void *ptr);
|
68
|
+
int sp_set(void *db, const void *k, size_t ksize, const void *v, size_t vsize);
|
69
|
+
int sp_delete(void *db, const void *k, size_t ksize);
|
70
|
+
int sp_get(void *db, const void *k, size_t ksize, void **v, size_t *vsize);
|
71
|
+
void *sp_cursor(void *db, sporder, const void *k, size_t ksize);
|
72
|
+
int sp_fetch(void *cur);
|
73
|
+
const char *sp_key(void *cur);
|
74
|
+
size_t sp_keysize(void *cur);
|
75
|
+
const char *sp_value(void *cur);
|
76
|
+
size_t sp_valuesize(void *cur);
|
77
|
+
char *sp_error(void *ptr);
|
78
|
+
void sp_stat(void *ptr, spstat*);
|
79
|
+
|
80
|
+
#ifdef __cplusplus
|
81
|
+
}
|
82
|
+
#endif
|
83
|
+
|
84
|
+
#endif
|