File: dbm_bdb.c

package info (click to toggle)
freecell-solver 3.26.0-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 4,864 kB
  • ctags: 3,658
  • sloc: ansic: 34,721; perl: 12,320; xml: 5,999; python: 1,149; sh: 965; ruby: 347; cpp: 304; makefile: 151
file content (157 lines) | stat: -rw-r--r-- 3,655 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <db.h>

#include "dbm_solver.h"

typedef struct
{
    DB * dbp;
    DBT key, data;
} dbm_t;

void fc_solve_dbm_store_init(fcs_dbm_store_t * store, const char * path)
{
    dbm_t * db = SMALLOC1(db);

    int ret;

    if ((ret = db_create(&(db->dbp), NULL, 0)) != 0)
    {
        fprintf(stderr, "db_create: %s\n", db_strerror(ret));
        exit (1);
    }

    if ((ret = db->dbp->open(db->dbp,
        NULL, path, NULL, DB_BTREE, DB_CREATE, 0664))
            != 0)
    {
        db->dbp->err(db->dbp, ret, "%s", path);
        goto err;
    }
    memset(&(db->key), 0, sizeof(db->key));
    memset(&(db->data), 0, sizeof(db->data));
    *store = (fcs_dbm_store_t)db;
    return;

    err:
    int t_ret;
    if ((t_ret = db->dbp->close(db->dbp, 0)) != 0 && ret == 0)
    {
        ret = t_ret;
    }
    exit(ret);
}

fcs_bool_t fc_solve_dbm_store_does_key_exist(
    fcs_dbm_store_t store,
    const unsigned char * key_raw
)
{
    unsigned char dummy[100];

    dbm_t * db = (dbm_t *)store;
    db->key.data = (unsigned char *)key_raw+1;
    db->key.size = key_raw[0];
    db->data.data = dummy;
    db->data.size = sizeof(dummy);

    int ret;
    if ((ret = db->dbp->get(db->dbp, NULL, &(db->key), &(db->data), 0)) == 0)
    {
        return TRUE;
    }
    else if (ret == DB_NOTFOUND)
    {
        return FALSE;
    }
    else
    {
        int t_ret;
        db->dbp->err(db->dbp, ret, "DB->get");
        if ((t_ret = db->dbp->close(db->dbp, 0)) != 0 && ret == 0)
        {
            ret = t_ret;
        }
        exit(ret);
    }
}

fcs_bool_t fc_solve_dbm_store_lookup_parent(
    fcs_dbm_store_t store,
    const unsigned char * key_raw,
    unsigned char * parent
)
{
    dbm_t * db = (dbm_t *)store;
    db->key.data = (unsigned char *)key_raw+1;
    db->key.size = key_raw[0];
    db->data.data = parent+1;
    db->data.size = sizeof(fcs_encoded_state_buffer_t)-1;

    int ret;
    if ((ret = db->dbp->get(db->dbp, NULL, &(db->key), &(db->data), 0)) == 0)
    {
        parent[0] = db->data.size-1;
        return TRUE;
    }
    else if (ret == DB_NOTFOUND)
    {
        return FALSE;
    }
    else
    {
        db->dbp->err(db->dbp, ret, "DB->get");
        if ((int t_ret = db->dbp->close(db->dbp, 0)) != 0 && ret == 0)
        {
            ret = t_ret;
        }
        exit(ret);
    }
}

#define MAX_ITEMS_IN_TRANSACTION 10000
extern void fc_solve_dbm_store_offload_pre_cache(
    fcs_dbm_store_t store,
    fcs_pre_cache_t * pre_cache
)
{
    dbm_t * const db = (dbm_t *)store;
    dict_t * const kaz_tree = pre_cache->kaz_tree;
    DB * const dbp = db->dbp;

    for (dnode_t * node = fc_solve_kaz_tree_first(kaz_tree);
            node ;
            node = fc_solve_kaz_tree_next(kaz_tree, node)
            )
    {
        fcs_pre_cache_key_val_pair_t * const kv =
            (fcs_pre_cache_key_val_pair_t *)(node->dict_key);

        db->key.data = kv->key.s+1;
        db->key.size = kv->key.s[0];
        db->data.data = kv->parent.s+1;
        db->data.size = kv->parent.s[0];
        if ((int ret = dbp->put(dbp, NULL, &(db->key), &(db->data), 0)) != 0)
        {
            dbp->err(dbp, ret, "DB->put");
            if ((int t_ret = dbp->close(dbp, 0)) != 0 && ret == 0)
            {
                ret = t_ret;
            }
            exit (ret);
        }
    }
}

extern void fc_solve_dbm_store_destroy(fcs_dbm_store_t store)
{
    dbm_t * const db = (dbm_t *)store;
    if ((int ret = db->dbp->close(db->dbp, 0)) != 0)
    {
        fprintf(stderr, "DB close failed with ret=%d\n", ret);
        exit(-1);
    }
    free(db);
}