⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdbm.c

📁 Apache V2.0.15 Alpha For Linuxhttpd-2_0_15-alpha.tar.Z
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights * reserved. * * 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. * * 3. The end-user documentation included with the redistribution, *    if any, must include the following acknowledgment: *       "This product includes software developed by the *        Apache Software Foundation (http://www.apache.org/)." *    Alternately, this acknowledgment may appear in the software itself, *    if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written *    permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", *    nor may "Apache" appear in their name, without prior written *    permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR * ITS 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. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation.  For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. *//* * sdbm - ndbm work-alike hashed database library * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978). * author: oz@nexus.yorku.ca * ex-public domain, ported to APR for Apache 2 * core routines */#include "apr.h"#include "apr_file_io.h"#include "apr_strings.h"#include "apr_errno.h"#include "apr_sdbm.h"#include "sdbm_tune.h"#include "sdbm_pair.h"#include "sdbm_private.h"#include <string.h>     /* for memset() */#include <stdlib.h>     /* for malloc() and free() *//* * forward */static int getdbit (SDBM *, long);static apr_status_t setdbit(SDBM *, long);static apr_status_t getpage(SDBM *db, long);static sdbm_datum getnext(SDBM *db);static apr_status_t makroom(SDBM *, long, int);/* * useful macros */#define SDBM_IOERR	0x2	       /* data base I/O error */#define bad(x)		((x).dptr == NULL || (x).dsize <= 0)#define exhash(item)	sdbm_hash((item).dptr, (item).dsize)#define ioerr(db)	((db)->flags |= SDBM_IOERR)/* ### Does anything need these externally? */#define sdbm_dirfno(db)	((db)->dirf)#define sdbm_pagfno(db)	((db)->pagf)#define OFF_PAG(off)	(apr_off_t) (off) * PBLKSIZ#define OFF_DIR(off)	(apr_off_t) (off) * DBLKSIZstatic long masks[] = {	000000000000, 000000000001, 000000000003, 000000000007,	000000000017, 000000000037, 000000000077, 000000000177,	000000000377, 000000000777, 000000001777, 000000003777,	000000007777, 000000017777, 000000037777, 000000077777,	000000177777, 000000377777, 000000777777, 000001777777,	000003777777, 000007777777, 000017777777, 000037777777,	000077777777, 000177777777, 000377777777, 000777777777,	001777777777, 003777777777, 007777777777, 017777777777};const sdbm_datum sdbm_nullitem = { NULL, 0 };static apr_status_t database_cleanup(void *data){    SDBM *db = data;    (void) apr_file_close(db->dirf);    (void) sdbm_unlock(db);    (void) apr_file_close(db->pagf);    free(db);    return APR_SUCCESS;}apr_status_tsdbm_open(SDBM **db, const char *file, apr_int32_t flags, apr_fileperms_t perms, apr_pool_t *p){    char *dirname = apr_pstrcat(p, file, SDBM_DIRFEXT, NULL);    char *pagname = apr_pstrcat(p, file, SDBM_PAGFEXT, NULL);        return sdbm_prep(db, dirname, pagname, flags, perms, p);}apr_status_tsdbm_prep(SDBM **pdb, const char *dirname, const char *pagname, 	  apr_int32_t flags, apr_fileperms_t perms, apr_pool_t *p){        SDBM *db;        apr_finfo_t finfo;	apr_status_t status;        *pdb = NULL;	db = malloc(sizeof(*db));        memset(db, 0, sizeof(*db));	db->pool = p;        /*         * adjust user flags so that WRONLY becomes RDWR,          * as required by this package. Also set our internal         * flag for RDONLY if needed.         */	if (!(flags & APR_WRITE)) {	    db->flags = SDBM_RDONLY;	}	flags |= APR_BINARY | APR_READ;        /*         * open the files in sequence, and stat the dirfile.         * If we fail anywhere, undo everything, return NULL.         */	if ((status = apr_file_open(&db->pagf, pagname, flags, perms, p))	    != APR_SUCCESS)            goto error;        if ((status = sdbm_lock(db)) != APR_SUCCESS)            goto error;        if ((status = apr_file_open(&db->dirf, dirname, flags, perms, p))            != APR_SUCCESS)            goto error;        /*         * need the dirfile size to establish max bit number.         */        if ((status = apr_file_info_get(&finfo, APR_FINFO_SIZE, db->dirf))                 != APR_SUCCESS)            goto error;        /*         * zero size: either a fresh database, or one with a single,         * unsplit data page: dirpage is all zeros.         */        db->dirbno = (!finfo.size) ? 0 : -1;        db->pagbno = -1;        db->maxbno = finfo.size * BYTESIZ;        /* (apr_pcalloc zeroed the buffers) */        /* make sure that we close the database at some point */        apr_pool_cleanup_register(p, db, database_cleanup, apr_pool_cleanup_null);        /* Done! */        *pdb = db;        return APR_SUCCESS;  error:        if (db->dirf != NULL)            (void) apr_file_close(db->dirf);        if (db->pagf != NULL) {            (void) sdbm_unlock(db);            (void) apr_file_close(db->pagf);        }        free(db);        return status;}voidsdbm_close(SDBM *db){    (void) apr_pool_cleanup_run(db->pool, db, database_cleanup);}sdbm_datumsdbm_fetch(SDBM *db, sdbm_datum key){	if (db == NULL || bad(key))		return sdbm_nullitem;	if (getpage(db, exhash(key)) == APR_SUCCESS)		return getpair(db->pagbuf, key);	ioerr(db);	return sdbm_nullitem;}static apr_status_t write_page(SDBM *db, const char *buf, long pagno){    apr_status_t status;    apr_off_t off = OFF_PAG(pagno);        if ((status = apr_file_seek(db->pagf, APR_SET, &off)) != APR_SUCCESS ||	(status = apr_file_write_full(db->pagf, buf, PBLKSIZ, NULL)) != APR_SUCCESS) {	ioerr(db);	return status;    }        return APR_SUCCESS;}apr_status_tsdbm_delete(SDBM *db, const sdbm_datum key){	apr_status_t status;	if (db == NULL || bad(key))		return APR_EINVAL;	if (sdbm_rdonly(db))		return APR_EINVAL;	if (getpage(db, exhash(key)) == APR_SUCCESS) {		if (!delpair(db->pagbuf, key))                        /* ### should we define some APRUTIL codes? */			return APR_EGENERAL;/* * update the page file */		if ((status = write_page(db, db->pagbuf, db->pagbno)) != APR_SUCCESS)		    return status;		return APR_SUCCESS;	}	ioerr(db);	return APR_EACCES;}apr_status_t sdbm_store(SDBM *db, sdbm_datum key, sdbm_datum val, int flags){	int need;	register long hash;	apr_status_t status;	if (db == NULL || bad(key))		return APR_EINVAL;	if (sdbm_rdonly(db))		return APR_EINVAL;	need = key.dsize + val.dsize;/* * is the pair too big (or too small) for this database ?? */	if (need < 0 || need > PAIRMAX)		return APR_EINVAL;	if ((status = getpage(db, (hash = exhash(key)))) == APR_SUCCESS) {/* * if we need to replace, delete the key/data pair * first. If it is not there, ignore. */		if (flags == SDBM_REPLACE)			(void) delpair(db->pagbuf, key);#ifdef SEEDUPS		else if (duppair(db->pagbuf, key))			return APR_EEXIST;#endif/* * if we do not have enough room, we have to split. */		if (!fitpair(db->pagbuf, need))		    if ((status = makroom(db, hash, need)) != APR_SUCCESS)			return status;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -