tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: RFC: Constant Database Support



For the archive:
Attached is a simple dbopen(3) like wrapper around cdbr/cdbw. I don't
intend to include this at the same, because the db(3) interface is not
really friendly to memory mapped databases. It can be revisited at a
later time though.

Joerg
/*      $NetBSD$        */
/*-
 * Copyright (c) 2010 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Joerg Sonnenberger.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__RCSID("$NetBSD");

#include <sys/endian.h>
#include <cdbr.h>
#include <db.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

struct cdbr_simple {
        DB db;
        uint32_t cursor;
};

#define DB_CDBR 4

static int
cdbr_simple_close(DB *dbp)
{
        cdbr_close(dbp->internal);
        free(dbp);
        return 0;
}

static int
cdbr_simple_del(const DB *dbp, const DBT *key, unsigned int flags)
{
        errno = EBADF;
        return -1;
}

static int
cdbr_simple_fd(const DB *dbp)
{
        errno = EBADF;
        return -1;
}

static int
cdbr_simple_get(const DB *dbp, const DBT *key, DBT *data, unsigned int flags)
{
        const uint8_t *d8;
        const void *d;
        size_t len;

        if (cdbr_find(dbp->internal, key->data, key->size, &d, &len))
                return -1;

        if (len < 4) {
                errno = EINVAL;
                return -1;
        }
        d8 = d;
        if (le32dec(d8) != key->size || key->size > len)
                return 1;
        if (memcmp(d8 + 4, key->data, key->size))
                return 1;
        data->size = len - key->size - 4;
        data->data = __UNCONST(d8) + 4 + key->size;

        return 0;
}

static int
cdbr_simple_put(const DB *dbp, DBT *key, const DBT *data, unsigned int flags)
{
        errno = EBADF;
        return -1;
}

static int
cdbr_simple_sync(const DB *dbp, unsigned int flags)
{
        return 0;
}

static int
cdbr_simple_seq(const DB *dbp, DBT *key, DBT *data, unsigned int flags)
{
        struct cdbr_simple *cdbr = (struct cdbr_simple *)dbp;
        size_t len;
        const void *d;
        const uint8_t *d8;

        switch (flags) {
        case R_FIRST:
                cdbr->cursor = 0;
                break;
        case R_NEXT:
                break;
        default:
                errno = EINVAL;
                return -1;
        }

        if (cdbr_get(cdbr->db.internal, cdbr->cursor++, &d, &len)) {
                cdbr->cursor = 0;
                return 1;
        }
        if (len < 4) {
                errno = EINVAL;
                return -1;
        }
        d8 = d;
        key->size = le32dec(d8);
        if (key->size > len - 4) {
                errno = EINVAL;
                return -1;
        }
        key->data = __UNCONST(d8 + 4);
        data->size = len - key->size - 4;
        data->data = __UNCONST(d8) + 4 + key->size;
        return 0;
}

DB *
cdbr_simple_open(const char *path)
{
        struct cdbr_simple *cdbrp;
        DB *dbp;

        cdbrp = calloc(1, sizeof(*cdbrp));
        cdbrp->cursor = 0;
        dbp = &cdbrp->db;

        dbp->type = DB_CDBR;
        if ((dbp->internal = cdbr_open(path, CDBR_DEFAULT)) == NULL) {
                free(dbp);
                return NULL;
        }
        dbp->close = cdbr_simple_close;
        dbp->del = cdbr_simple_del;
        dbp->fd = cdbr_simple_fd;
        dbp->get = cdbr_simple_get;
        dbp->put = cdbr_simple_put;
        dbp->seq = cdbr_simple_seq;
        dbp->sync = cdbr_simple_sync;

        return dbp;
}
/*      $NetBSD$        */
/*-
 * Copyright (c) 2010 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Joerg Sonnenberger.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__RCSID("$NetBSD");

#include <sys/endian.h>
#include <cdbw.h>
#include <db.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define DB_CDBW 5

struct cdbw_simple {
        DB db;
        int fd;
};

static int
cdbw_simple_close(DB *dbp)
{
        struct cdbw_simple *cdbw = (struct cdbw_simple *)dbp;
        int rv;

        rv = cdbw_output(dbp->internal, cdbw->fd, "simple cdb", NULL);
        cdbw_close(dbp->internal);
        close(cdbw->fd);
        free(cdbw);
        return rv;
}

static int
cdbw_simple_del(const DB *dbp, const DBT *key, unsigned int flags)
{
        errno = EBADF;
        return -1;
}

static int
cdbw_simple_fd(const DB *dbp)
{
        errno = EBADF;
        return -1;
}

static int
cdbw_simple_get(const DB *dbp, const DBT *key, DBT *data, unsigned int flags)
{
        errno = EBADF;
        return -1;
}

static int
cdbw_simple_put(const DB *dbp, DBT *key, const DBT *data, unsigned int flags)
{
        size_t len;
        uint8_t *d;
        int rv;

        if (flags != R_NOOVERWRITE) {
                errno = EINVAL;
                return -1;
        }

        len = key->size + data->size + 4;
        if ((d = malloc(len)) == NULL)
                return -1;
        le32enc(d, key->size);
        memcpy(d + 4, key->data, key->size);
        memcpy(d + 4 + key->size, data->data, data->size);

        rv = cdbw_put(dbp->internal, key->data, key->size, d, len);
        free(d);
        return rv == 0 ? 0 : 1;
}

static int
cdbw_simple_sync(const DB *dbp, unsigned int flags)
{
        return 0;
}

static int
cdbw_simple_seq(const DB *dbp, DBT *key, DBT *data, unsigned int flags)
{
        errno = EBADF;
        return -1;
}

DB *
cdbw_simple_open(const char *path, int flags, mode_t mode)
{
        struct cdbw_simple *cdbwp;
        DB *dbp;

        cdbwp = calloc(1, sizeof(*cdbwp));
        dbp = &cdbwp->db;

        dbp->type = DB_CDBW;
        if ((dbp->internal = cdbw_open()) == NULL) {
                free(dbp);
                return NULL;
        }
        if ((cdbwp->fd = open(path, flags, mode)) == -1) {
                cdbw_close(dbp->internal);
                free(cdbwp);
                return NULL;
        }
        dbp->close = cdbw_simple_close;
        dbp->del = cdbw_simple_del;
        dbp->fd = cdbw_simple_fd;
        dbp->get = cdbw_simple_get;
        dbp->put = cdbw_simple_put;
        dbp->seq = cdbw_simple_seq;
        dbp->sync = cdbw_simple_sync;

        return dbp;
}


Home | Main Index | Thread Index | Old Index