pjs/ef/gc/hash/dynahash.h

166 строки
5.1 KiB
C

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*******************************************************************************
* Hash Tables: Based on Larson's in-memory adaption of linear hashing
* [CACM, vol 31, #4, 1988 pp 446-457]
******************************************************************************/
#ifndef dynahash_h__
#define dynahash_h__
#include "prtypes.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*******************************************************************************
* PLDynahash
******************************************************************************/
#define PL_DYNAHASH_SIZE (1 << 16)
#define PL_DYNAHASH_BUCKETSIZE_SHIFT 3
#define PL_DYNAHASH_BUCKETSIZE (1 << PL_DYNAHASH_BUCKETSIZE_SHIFT)
#define PL_DYNAHASH_MAX_DIR_SIZE (PL_DYNAHASH_SIZE / PL_DYNAHASH_BUCKETSIZE)
#define PL_DYNAHASH_LOAD_FACTOR 2
#define PL_DYNAHASH_MAGIC_NUMBER 65521U
typedef struct PLDynahashElement {
struct PLDynahashElement* next;
/* other data follows */
} PLDynahashElement;
typedef PLDynahashElement* PLHashBucket; /* array of PLDynahashElement handles */
typedef PLHashBucket* PLHashDir; /* array of HashBucket handles */
typedef PRUword
(PR_CALLBACK* PLHashFun)(void* context, PLDynahashElement* x);
typedef PRBool
(PR_CALLBACK* PLEqualFun)(void* context, PLDynahashElement* x, PLDynahashElement* y);
typedef void
(PR_CALLBACK* PLDestroyFun)(void* context, PLDynahashElement* x);
typedef struct PLDynahash {
PLHashDir* directory;
PLHashFun hash;
PLEqualFun equal;
PLDestroyFun destroy;
PRUint32 keyCount;
PRUint16 nextBucketToSplit;
PRUint16 maxSize;
PRUint16 bucketCount;
void* context;
#ifdef PL_DYNAHASH_STATISTICS
PRUint32 accesses;
PRUint32 collisions;
PRUint32 expansions;
#endif /* PL_DYNAHASH_STATISTICS */
} PLDynahash;
/******************************************************************************/
PR_EXTERN(PRStatus)
PL_DynahashInit(PLDynahash* self, PRUint32 initialSize, PLHashFun hash,
PLEqualFun equal, PLDestroyFun del, void* context);
PR_EXTERN(void)
PL_DynahashCleanup(PLDynahash* self);
PR_EXTERN(PLDynahash*)
PL_NewDynahash(PRUint32 initialSize,
PLHashFun hash, PLEqualFun equal,
PLDestroyFun del, void* context);
PR_EXTERN(void)
PL_DynahashDestroy(PLDynahash* self);
PR_EXTERN(PLDynahashElement*)
PL_DynahashLookup(PLDynahash* self, PLDynahashElement* element);
PR_EXTERN(PRStatus)
PL_DynahashAdd(PLDynahash* self, PLDynahashElement* element, PRBool replace,
PLDynahashElement* *elementToDestroy);
PR_EXTERN(PLDynahashElement*)
PL_DynahashRemove(PLDynahash* self, PLDynahashElement* element);
PR_EXTERN(void)
PL_DynahashEmpty(PLDynahash* self);
#define PL_DynahashSize(self) ((self)->keyCount)
#ifdef DEBUG
PR_EXTERN(PRBool)
PL_DynahashIsValid(PLDynahash* self);
PR_EXTERN(PRBool)
PL_DynahashTest(void);
#endif /* NDEBUG */
/*******************************************************************************
* Hash Table Iterator
******************************************************************************/
typedef struct PLDynahashIterator {
PLDynahash* table;
PRBool done;
PRUint32 bucket;
PRInt32 bin;
PRInt32 curno;
PRUint32 lbucket;
PRInt32 lbin;
PRInt32 lcurno;
PLHashBucket* b;
PLDynahashElement* nextp;
PLDynahashElement* curp;
} PLDynahashIterator;
PR_EXTERN(void)
PL_DynahashIteratorInit(PLDynahashIterator* self, PLDynahash* ht);
PR_EXTERN(PLDynahashElement*)
PL_DynahashIteratorNext(PLDynahashIterator* self);
#define PL_CurrentDynahashIterator(self) ((self)->curp)
PR_EXTERN(PRUword)
PL_DynahashIteratorCurrentAddress(PLDynahashIterator* self);
PR_EXTERN(PLDynahashElement*)
PL_DynahashIteratorRemoveCurrent(PLDynahashIterator* self);
#define PL_DynahashIteratorIsDone(self) ((self)->done)
PR_EXTERN(void)
PL_DynahashIteratorReset(PLDynahashIterator* self, PLDynahash* ht);
/******************************************************************************/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* dynahash_h__ */
/******************************************************************************/