gecko-dev/modules/libnls/headers/hashtab.h
1998-05-27 02:02:27 +00:00

278 lines
8.8 KiB
C++

/*
*****************************************************************************************
* *
* COPYRIGHT: *
* (C) Copyright Taligent, Inc., 1997 *
* (C) Copyright International Business Machines Corporation, 1997 *
* Licensed Material - Program-Property of IBM - All Rights Reserved. *
* US Government Users Restricted Rights - Use, duplication, or disclosure *
* restricted by GSA ADP Schedule Contract with IBM Corp. *
* *
*****************************************************************************************
*
* File hashtab.h
*
* Created by: Alan Liu
* Based on hashtab2.java by Mark Davis
*
* Modification History:
*
* Date Name Description
* 04/29/97 aliu Added key and value deletion protocol. Add class and method
* documentation paragraphs. Made size() and isEmpty() inline.
*****************************************************************************************
*/
#ifndef _HASHTAB
#define _HASHTAB
#ifndef _PTYPES
#include "ptypes.h"
#endif
#ifndef _UNISTRING
#include "unistring.h"
#endif
//-------------------------------------------------------------------------------
// Hashkey is the abstract base class for keys in a Hashtable.
#ifdef NLS_MAC
#pragma export on
#endif
class T_UTILITY_API Hashkey
{
public:
virtual ~Hashkey() {}
virtual t_int32 hashCode() const = 0;
virtual t_bool operator==(const Hashkey&) const = 0;
virtual ClassID getDynamicClassID() const = 0;
};
//--------------------------------------------------------------------------------
// UnicodeStringKey interface
// This class is a key which is a UnicodeString.
//--------------------------------------------------------------------------------
// It would be nice to make this class multiply-inherit from Hashkey and
// UnicodeString, but that's going to create too many problems.
// Idea for future change: For more flexibility, we could add a constructor
// that adopted a UnicodeString*, and then add a bool to indicate whether the
// string was owned or not.
class T_UTILITY_API UnicodeStringKey : public Hashkey
{
public:
UnicodeStringKey() {}
UnicodeStringKey(const UnicodeString&);
virtual ~UnicodeStringKey();
// Hashkey protocol
virtual t_int32 hashCode() const;
virtual t_bool operator==(const Hashkey&) const;
inline const UnicodeString* getString() const { return &fString; }
inline void operator=(const UnicodeString& s) { fString=s; }
virtual ClassID getDynamicClassID() const { return (ClassID)&fgClassID; }
static ClassID getStaticClassID() { return (ClassID)&fgClassID; }
private:
static char fgClassID;
UnicodeString fString;
};
//--------------------------------------------------------------------------------
// LongKey interface
// This class is a key which is a long.
//--------------------------------------------------------------------------------
class T_UTILITY_API LongKey : public Hashkey
{
public:
LongKey(t_int32 value);
virtual ~LongKey();
// Hashkey protocol
virtual t_int32 hashCode() const;
virtual t_bool operator==(const Hashkey&) const;
inline t_int32 getLong() const { return fLong; }
virtual ClassID getDynamicClassID() const { return (ClassID)&fgClassID; }
static ClassID getStaticClassID() { return (ClassID)&fgClassID; }
private:
static char fgClassID;
t_int32 fLong;
};
//--------------------------------------------------------------------------------
// Hashtable
//--------------------------------------------------------------------------------
/**
* Hashtable stores key-value pairs and does efficient lookup based on keys.
* It also provides a protocol for enumerating through the key-value pairs
* (although it does so in no particular order). Hashtable objects may
* optionally own the keys or the values it contains. Keys must derive
* from the abstract base class Hashkey. Values are stored as void* pointers.
*/
class T_UTILITY_API Hashtable
{
public:
typedef void* Object;
typedef void (*ValueDeleter)(Object valuePointer);
public:
/**
* Construct a new hashtable. By default, a Hashtable does not own
* its keys or values. If deleteKeys is true, then keys will be deleted.
* If deleteFunction is nonzero, then values will be deleted by calling
* deleteFunction(valuePointer). Ownershipt of keys and values effects
* the behavior of the destructor and the put() and remove() methods.
*/
Hashtable();
Hashtable(t_bool deleteKeys, ValueDeleter deleteFunction = 0);
Hashtable(t_int32 initialSize);
/**
* Destroy this object. If values are to be deleted, delete all contained
* values. If keys are to be deleted, delete all contained keys.
*/
virtual ~Hashtable();
/**
* Return the number of key-value pairs in this hashtable.
*/
t_int32 size();
/**
* Return true if there are no key-value pairs in this hashtable.
*/
t_bool isEmpty();
/**
* Add a key-value pair to this hashtable. If a pair already exists with a
* key which is equal to the new key (as determined by operator==()), then
* the previous key-value pair are handled according to whether or not keys
* and values are owned by this object. If keys are owned, then the
* previous key is deleted; otherwise, the previous key is considered the
* client's responsibility -- it is dropped on the floor. The client must
* delete it using a previously saved pointer to it. If values are owned,
* then the previous value is deleted and null is returned; otherwise, the
* previous value is returned. If there is no pre-existing key which matches
* then null is always returned.
*/
Object put(Hashkey* key, Object value);
/**
* Return the value previously put() with a matching key. A key matches
* if its operator==() method returns true for the specified key. If there
* is no matching key, return null.
*/
Object get(const Hashkey& key) const;
/**
* Remove and return the value previously put() with a matching key. A key
* matches if its operator==() method returns true for the specified key.
* If there is no matching key, return null. The pre-existing key and value
* are handled according to whether or not keys and values are owned by this
* object. See documentation for put() for details.
*/
Object remove(const Hashkey& key);
/**
* Specify whether keys are to be deleted or not. This effects the behavior
* of the destructor and the methods put() and remove().
*/
void setDeleteKeys(t_bool deleteKeys);
/**
* Specify whether values are to be deleted or not. This effects the behavior
* of the destructor and the methods put() and remove(). If deleteFunction
* is null, then values are not deleted. Otherwise, deleteFunction(value) is
* called for each value to be deleted.
*/
void setValueDeleter(ValueDeleter deleteFunction);
public:
class T_UTILITY_API Enumeration
{
public:
Enumeration(const Hashtable& h);
t_bool hasMoreElements();
t_bool nextElement(Hashkey*& fillInKey, Object& fillInValue);
Object removeElement(); // Removes the last element returned by nextElement()
private:
Enumeration(const Enumeration&); // Disallowed, not implemented
Enumeration& operator=(const Enumeration&); // Disallowed, not implemented
Hashtable& fHashtable; // Don't make this const; AIX compiler chokes
t_int32 fPosition;
t_int32 fRemainder;
};
friend class Enumeration;
Enumeration* createEnumeration() const;
private:
void initialize(t_int32 primeIndex);
void rehash();
void putInternal(Hashkey* key, t_int32 hash, Object value);
t_int32 find(const Hashkey& key, t_int32 hash) const;
static t_int32 leastGreaterPrimeIndex(t_int32 source);
private:
t_int32 primeIndex;
t_int32 highWaterMark;
t_int32 lowWaterMark;
float highWaterFactor;
float lowWaterFactor;
t_int32 count;
// We use three arrays to minimize allocations
t_int32* hashes;
Object* values;
Hashkey** keyList;
t_int32 length; // Length of hashes, values, keyList
// Deletion protocol
t_bool fDeleteKeys;
ValueDeleter fValueDeleter;
static const t_int32 PRIMES[];
static const t_int32 PRIMES_LENGTH;
// Special hash values
static const t_int32 DELETED;
static const t_int32 EMPTY;
static const t_int32 MAX_UNUSED;
};
#ifdef NLS_MAC
#pragma export off
#endif
//--------------------------------------------------------------------------------
// Inline Hashtable methods
//--------------------------------------------------------------------------------
inline t_int32 Hashtable::size()
{
return count;
}
inline t_bool Hashtable::isEmpty()
{
return count == 0;
}
#endif //_HASHTAB
//eof