#ifndef SP_REP_H_
#define SP_REP_H_
/*
* sophia database
* sphia.org
*
* Copyright (c) Dmitry Simonenko
* BSD License
*/
typedef struct spepoch spepoch;
typedef struct sprep sprep;
enum spepochtype {
SPUNDEF,
SPLIVE,
SPXFER,
SPDB
};
typedef enum spepochtype spepochtype;
#define SPRNONE 0
#define SPRDB 1
#define SPRDBI 2
#define SPRLOG 4
#define SPRLOGI 8
struct spepoch {
uint32_t epoch;
uint32_t n; /* count of pages */
uint32_t ngc; /* count of gc pages */
uint32_t nupdate; /* count of updated keys */
spepochtype type; /* epoch life-cycle state */
uint32_t recover; /* recover status */
spfile log, db;
spspinlock lock; /* db lock */
splist pages; /* list of associated pages */
splist link;
};
struct sprep {
spa *a;
uint32_t epoch;
splist l;
int n;
int ndb;
int nxfer;
};
void sp_repinit(sprep*, spa*);
void sp_repfree(sprep*);
int sp_repprepare(sprep*);
spepoch *sp_repmatch(sprep *r, uint32_t epoch);
spepoch *sp_repalloc(sprep*, uint32_t);
void sp_repattach(sprep*, spepoch*);
void sp_repdetach(sprep*, spepoch*);
void sp_repset(sprep*, spepoch*, spepochtype);
static inline uint32_t
sp_repepoch(sprep *r) {
return r->epoch;
}
static inline void
sp_repepochincrement(sprep *r) {
r->epoch++;
}
static inline void
sp_replockall(sprep *r) {
register splist *i;
sp_listforeach(&r->l, i) {
register spepoch *e = spcast(i, spepoch, link);
sp_lock(&e->lock);
}
}
static inline void
sp_repunlockall(sprep *r) {
register splist *i;
sp_listforeach(&r->l, i) {
register spepoch *e = spcast(i, spepoch, link);
sp_unlock(&e->lock);
}
}
static inline spepoch*
sp_replive(sprep *r) {
register spepoch *e = spcast(r->l.prev, spepoch, link);
assert(e->type == SPLIVE);
return e;
}
static inline spepoch*
sp_repxfer(sprep *r) {
register splist *i;
sp_listforeach(&r->l, i) {
register spepoch *s = spcast(i, spepoch, link);
if (s->type == SPXFER)
return s;
}
return NULL;
}
static inline spepoch*
sp_repgc(sprep *r, float factor) {
register splist *i;
sp_listforeach(&r->l, i) {
register spepoch *s = spcast(i, spepoch, link);
if (s->type != SPDB)
continue;
if (s->ngc > (s->n * factor))
return s;
}
return NULL;
}
#endif