Add cdbr_open_mem.

This commit is contained in:
joerg 2013-12-05 21:17:23 +00:00
parent 13bf828c30
commit fcff7df126
4 changed files with 88 additions and 23 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cdbr.h,v 1.1 2010/04/25 00:54:45 joerg Exp $ */
/* $NetBSD: cdbr.h,v 1.2 2013/12/05 21:17:23 joerg Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -45,6 +45,8 @@ struct cdbr;
__BEGIN_DECLS
struct cdbr *cdbr_open(const char *, int);
struct cdbr *cdbr_open_mem(void *, size_t, int,
void (*)(void *, void *, size_t), void *);
uint32_t cdbr_entries(struct cdbr *);
int cdbr_get(struct cdbr *, uint32_t, const void **, size_t *);
int cdbr_find(struct cdbr *, const void *, size_t,

View File

@ -1,4 +1,4 @@
.\" $NetBSD: cdbr.3,v 1.3 2013/07/20 21:39:56 wiz Exp $
.\" $NetBSD: cdbr.3,v 1.4 2013/12/05 21:17:23 joerg Exp $
.\"
.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -28,12 +28,13 @@
.\" 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.
.Dd March 3, 2010
.Dd December 5, 2013
.Dt CDBR 3
.Os
.Sh NAME
.Nm cdbr
.Nm cdbr_open ,
.Nm cdbr_open_mem ,
.Nm cdbr_entries ,
.Nm cdbr_get ,
.Nm cdbr_find ,
@ -43,6 +44,13 @@
.Sh SYNOPSIS
.Ft "struct cdbr *"
.Fn cdbr_open "const char *path" "int flags"
.Ft "struct cdbr *"
.Fo cdbr_open_mem
.Fa "void *base"
.Fa "size_t size"
.Fa "void (*unmap)(void *, void *, size_t)"
.Fa "void *cookie"
.Fc
.Ft uint32_t
.Fn cdbr_entries "struct cdbr *cdbr"
.Ft int
@ -78,6 +86,25 @@ returned by
and
.Fn cdbr_find
is invalidated.
.Fn cdbr_open_mem
works like
.Fn cdbr_open ,
but takes a memory reference to the content of the database file.
If
.Va unmap
is not
.Dv NULL ,
it is called by
.Fn cdbr_close
with
.Va cookie ,
.Va base
and
.Va size
as arguments.
It is not called by
.Fn cdbr_open_mem
on error.
.Pp
The number of records in the database can be obtained by calling
.Fn cdbr_entries .

View File

@ -1,4 +1,4 @@
/* $NetBSD: cdbr.c,v 1.4 2012/09/27 00:37:43 joerg Exp $ */
/* $NetBSD: cdbr.c,v 1.5 2013/12/05 21:17:23 joerg Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
@ -36,7 +36,7 @@
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: cdbr.c,v 1.4 2012/09/27 00:37:43 joerg Exp $");
__RCSID("$NetBSD: cdbr.c,v 1.5 2013/12/05 21:17:23 joerg Exp $");
#include "namespace.h"
@ -53,6 +53,7 @@ __RCSID("$NetBSD: cdbr.c,v 1.4 2012/09/27 00:37:43 joerg Exp $");
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@ -62,6 +63,7 @@ __weak_alias(cdbr_close,_cdbr_close)
__weak_alias(cdbr_find,_cdbr_find)
__weak_alias(cdbr_get,_cdbr_get)
__weak_alias(cdbr_open,_cdbr_open)
__weak_alias(cdbr_open_mem,_cdbr_open_mem)
#endif
#if HAVE_NBTOOL_CONFIG_H
@ -70,6 +72,8 @@ __weak_alias(cdbr_open,_cdbr_open)
#endif
struct cdbr {
void (*unmap)(void *, void *, size_t);
void *cookie;
uint8_t *mmap_base;
size_t mmap_size;
@ -91,27 +95,63 @@ struct cdbr {
uint8_t entries_index_s1, entries_index_s2;
};
static void
cdbr_unmap(void *cookie __unused, void *base, size_t size)
{
munmap(base, size);
}
/* ARGSUSED */
struct cdbr *
cdbr_open(const char *path, int flags)
{
uint8_t buf[40];
void *base;
size_t size;
int fd;
struct cdbr *cdbr;
struct stat sb;
if ((fd = open(path, O_RDONLY)) == -1)
return NULL;
errno = EINVAL;
if (fstat(fd, &sb) == -1 ||
read(fd, buf, sizeof(buf)) != sizeof(buf) ||
memcmp(buf, "NBCDB\n\0\001", 8) ||
(cdbr = malloc(sizeof(*cdbr))) == NULL) {
if (fstat(fd, &sb) == -1) {
close(fd);
return NULL;
}
if (sb.st_size >= SSIZE_MAX) {
errno = EINVAL;
return NULL;
}
size = (size_t)sb.st_size;
base = mmap(NULL, size, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0);
close(fd);
if (base == MAP_FAILED)
return NULL;
cdbr = cdbr_open_mem(base, size, flags, cdbr_unmap, NULL);
if (cdbr == NULL)
munmap(base, size);
return cdbr;
}
struct cdbr *
cdbr_open_mem(void *base, size_t size, int flags,
void (*unmap)(void *, void *, size_t), void *cookie)
{
struct cdbr *cdbr;
uint8_t *buf = base;
if (size < 40 || memcmp(buf, "NBCDB\n\0\001", 8)) {
errno = EINVAL;
return NULL;
}
cdbr = malloc(sizeof(*cdbr));
cdbr->unmap = unmap;
cdbr->cookie = cookie;
cdbr->data_size = le32dec(buf + 24);
cdbr->entries = le32dec(buf + 28);
cdbr->entries_index = le32dec(buf + 32);
@ -131,14 +171,8 @@ cdbr_open(const char *path, int flags)
else
cdbr->index_size = 4;
cdbr->mmap_size = (size_t)sb.st_size;
cdbr->mmap_base = mmap(NULL, cdbr->mmap_size, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0);
close(fd);
if (cdbr->mmap_base == MAP_FAILED) {
free(cdbr);
return NULL;
}
cdbr->mmap_base = base;
cdbr->mmap_size = size;
cdbr->hash_base = cdbr->mmap_base + 40;
cdbr->offset_base = cdbr->hash_base + cdbr->entries_index * cdbr->index_size;
@ -154,7 +188,7 @@ cdbr_open(const char *path, int flags)
cdbr->data_base + cdbr->data_size >
cdbr->mmap_base + cdbr->mmap_size) {
errno = EINVAL;
cdbr_close(cdbr);
free(cdbr);
return NULL;
}
@ -255,6 +289,7 @@ cdbr_find(struct cdbr *cdbr, const void *key, size_t key_len,
void
cdbr_close(struct cdbr *cdbr)
{
munmap(cdbr->mmap_base, cdbr->mmap_size);
if (cdbr->unmap)
(*cdbr->unmap)(cdbr->cookie, cdbr->mmap_base, cdbr->mmap_size);
free(cdbr);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: namespace.h,v 1.169 2013/08/28 17:47:07 riastradh Exp $ */
/* $NetBSD: namespace.h,v 1.170 2013/12/05 21:17:23 joerg Exp $ */
/*-
* Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
@ -186,6 +186,7 @@
#define cdbr_find _cdbr_find
#define cdbr_get _cdbr_get
#define cdbr_open _cdbr_open
#define cdbr_open_mem _cdbr_open_mem
#define cdbw_close _cdbw_close
#define cdbw_open _cdbw_open
#define cdbw_put _cdbw_put