version 1.25, 2011/12/16 12:07:45 |
version 1.29, 2012/03/23 05:07:35 |
Line 123 static const struct type types[] = { |
|
Line 123 static const struct type types[] = { |
|
|
|
static DB *btree_open(void); |
static DB *btree_open(void); |
static int btree_read(const DBT *, const DBT *, |
static int btree_read(const DBT *, const DBT *, |
const struct mchars *, |
const struct mchars *, |
struct db_val *, char **); |
uint64_t *, recno_t *, char **); |
static int expreval(const struct expr *, int *); |
static int expreval(const struct expr *, int *); |
static void exprexec(const struct expr *, |
static void exprexec(const struct expr *, |
const char *, uint64_t, struct rec *); |
const char *, uint64_t, struct rec *); |
Line 153 btree_open(void) |
|
Line 153 btree_open(void) |
|
DB *db; |
DB *db; |
|
|
memset(&info, 0, sizeof(BTREEINFO)); |
memset(&info, 0, sizeof(BTREEINFO)); |
|
info.lorder = 4321; |
info.flags = R_DUP; |
info.flags = R_DUP; |
|
|
db = dbopen(MANDOC_DB, O_RDONLY, 0, DB_BTREE, &info); |
db = dbopen(MANDOC_DB, O_RDONLY, 0, DB_BTREE, &info); |
Line 167 btree_open(void) |
|
Line 168 btree_open(void) |
|
* Return 0 if the database is insane, else 1. |
* Return 0 if the database is insane, else 1. |
*/ |
*/ |
static int |
static int |
btree_read(const DBT *k, const DBT *v, |
btree_read(const DBT *k, const DBT *v, const struct mchars *mc, |
const struct mchars *mc, |
uint64_t *mask, recno_t *rec, char **buf) |
struct db_val *dbv, char **buf) |
|
{ |
{ |
const struct db_val *vp; |
uint64_t vbuf[2]; |
|
|
/* Are our sizes sane? */ |
/* Are our sizes sane? */ |
if (k->size < 2 || sizeof(struct db_val) != v->size) |
if (k->size < 2 || sizeof(vbuf) != v->size) |
return(0); |
return(0); |
|
|
/* Is our string nil-terminated? */ |
/* Is our string nil-terminated? */ |
if ('\0' != ((const char *)k->data)[(int)k->size - 1]) |
if ('\0' != ((const char *)k->data)[(int)k->size - 1]) |
return(0); |
return(0); |
|
|
vp = v->data; |
|
norm_string((const char *)k->data, mc, buf); |
norm_string((const char *)k->data, mc, buf); |
dbv->rec = betoh32(vp->rec); |
memcpy(vbuf, v->data, v->size); |
dbv->mask = betoh64(vp->mask); |
*mask = betoh64(vbuf[0]); |
|
*rec = betoh64(vbuf[1]); |
return(1); |
return(1); |
} |
} |
|
|
Line 197 btree_read(const DBT *k, const DBT *v, |
|
Line 197 btree_read(const DBT *k, const DBT *v, |
|
static size_t |
static size_t |
norm_utf8(unsigned int cp, char out[7]) |
norm_utf8(unsigned int cp, char out[7]) |
{ |
{ |
size_t rc; |
int rc; |
|
|
rc = 0; |
rc = 0; |
|
|
Line 238 norm_utf8(unsigned int cp, char out[7]) |
|
Line 238 norm_utf8(unsigned int cp, char out[7]) |
|
return(0); |
return(0); |
|
|
out[rc] = '\0'; |
out[rc] = '\0'; |
return(rc); |
return((size_t)rc); |
} |
} |
|
|
/* |
/* |
Line 380 index_read(const DBT *key, const DBT *val, int index, |
|
Line 380 index_read(const DBT *key, const DBT *val, int index, |
|
return(0); |
return(0); |
|
|
cp = val->data; |
cp = val->data; |
rec->res.rec = *(recno_t *)key->data; |
assert(sizeof(recno_t) == key->size); |
|
memcpy(&rec->res.rec, key->data, key->size); |
rec->res.volume = index; |
rec->res.volume = index; |
|
|
if ('d' == (type = *cp++)) |
if ('d' == (type = *cp++)) |
Line 474 single_search(struct rectree *tree, const struct opts |
|
Line 475 single_search(struct rectree *tree, const struct opts |
|
char *buf; |
char *buf; |
struct rec *rs; |
struct rec *rs; |
struct rec r; |
struct rec r; |
struct db_val vb; |
uint64_t mask; |
|
recno_t rec; |
|
|
root = -1; |
root = -1; |
leaf = -1; |
leaf = -1; |
Line 494 single_search(struct rectree *tree, const struct opts |
|
Line 496 single_search(struct rectree *tree, const struct opts |
|
} |
} |
|
|
while (0 == (ch = (*btree->seq)(btree, &key, &val, R_NEXT))) { |
while (0 == (ch = (*btree->seq)(btree, &key, &val, R_NEXT))) { |
if ( ! btree_read(&key, &val, mc, &vb, &buf)) |
if ( ! btree_read(&key, &val, mc, &mask, &rec, &buf)) |
break; |
break; |
|
|
/* |
/* |
* See if this keyword record matches any of the |
* See if this keyword record matches any of the |
* expressions we have stored. |
* expressions we have stored. |
*/ |
*/ |
if ( ! exprmark(expr, buf, vb.mask, NULL)) |
if ( ! exprmark(expr, buf, mask, NULL)) |
continue; |
continue; |
|
|
/* |
/* |
Line 511 single_search(struct rectree *tree, const struct opts |
|
Line 513 single_search(struct rectree *tree, const struct opts |
|
*/ |
*/ |
|
|
for (leaf = root; leaf >= 0; ) |
for (leaf = root; leaf >= 0; ) |
if (vb.rec > rs[leaf].res.rec && |
if (rec > rs[leaf].res.rec && |
rs[leaf].rhs >= 0) |
rs[leaf].rhs >= 0) |
leaf = rs[leaf].rhs; |
leaf = rs[leaf].rhs; |
else if (vb.rec < rs[leaf].res.rec && |
else if (rec < rs[leaf].res.rec && |
rs[leaf].lhs >= 0) |
rs[leaf].lhs >= 0) |
leaf = rs[leaf].lhs; |
leaf = rs[leaf].lhs; |
else |
else |
Line 526 single_search(struct rectree *tree, const struct opts |
|
Line 528 single_search(struct rectree *tree, const struct opts |
|
* try to evaluate it now and continue anyway. |
* try to evaluate it now and continue anyway. |
*/ |
*/ |
|
|
if (leaf >= 0 && rs[leaf].res.rec == vb.rec) { |
if (leaf >= 0 && rs[leaf].res.rec == rec) { |
if (0 == rs[leaf].matched) |
if (0 == rs[leaf].matched) |
exprexec(expr, buf, vb.mask, &rs[leaf]); |
exprexec(expr, buf, mask, &rs[leaf]); |
continue; |
continue; |
} |
} |
|
|
Line 538 single_search(struct rectree *tree, const struct opts |
|
Line 540 single_search(struct rectree *tree, const struct opts |
|
* database, then begin partial evaluation. |
* database, then begin partial evaluation. |
*/ |
*/ |
|
|
key.data = &vb.rec; |
key.data = &rec; |
key.size = sizeof(recno_t); |
key.size = sizeof(recno_t); |
|
|
if (0 != (*idx->get)(idx, &key, &val, 0)) |
if (0 != (*idx->get)(idx, &key, &val, 0)) |
Line 565 single_search(struct rectree *tree, const struct opts |
|
Line 567 single_search(struct rectree *tree, const struct opts |
|
rs[tree->len].matches = |
rs[tree->len].matches = |
mandoc_calloc(terms, sizeof(int)); |
mandoc_calloc(terms, sizeof(int)); |
|
|
exprexec(expr, buf, vb.mask, &rs[tree->len]); |
exprexec(expr, buf, mask, &rs[tree->len]); |
|
|
/* Append to our tree. */ |
/* Append to our tree. */ |
|
|
if (leaf >= 0) { |
if (leaf >= 0) { |
if (vb.rec > rs[leaf].res.rec) |
if (rec > rs[leaf].res.rec) |
rs[leaf].rhs = tree->len; |
rs[leaf].rhs = tree->len; |
else |
else |
rs[leaf].lhs = tree->len; |
rs[leaf].lhs = tree->len; |