mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 730825 - Part 2: remove nsDoubleHashtable.h; r=bsmedberg
This commit is contained in:
parent
ad1e586c68
commit
4cd89227bb
@ -95,7 +95,6 @@ EXPORTS = \
|
||||
nsCheapSets.h \
|
||||
nsCppSharedAllocator.h \
|
||||
nsCRT.h \
|
||||
nsDoubleHashtable.h \
|
||||
nsExpirationTracker.h \
|
||||
nsFixedSizeAllocator.h \
|
||||
nsHashtable.h \
|
||||
|
@ -1,483 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* nsDoubleHashtable.h is OBSOLETE. Use nsTHashtable or a derivative instead.
|
||||
*/
|
||||
|
||||
#ifndef __nsDoubleHashtable_h__
|
||||
#define __nsDoubleHashtable_h__
|
||||
|
||||
#include "pldhash.h"
|
||||
#include "nscore.h"
|
||||
#include "nsString.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
/*
|
||||
* This file provides several major things to make PLDHashTable easier to use:
|
||||
* - hash class macros for you to define a hashtable
|
||||
* - default key classes to use as superclasses for your entries
|
||||
* - empty maps for string, cstring, int and void
|
||||
*/
|
||||
|
||||
/*
|
||||
* USAGE
|
||||
*
|
||||
* To use nsDoubleHashtable macros
|
||||
* (1) Define an entry class
|
||||
* (2) Create the hash class
|
||||
* (3) Use the hash class
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* As an example, let's create a dictionary, a mapping from a string (the word)
|
||||
* to the pronunciation and definition of those words.
|
||||
*
|
||||
* (1) Define an entry class
|
||||
*
|
||||
* What we want here is an entry class that contains the word, the
|
||||
* pronunciation string, and the definition string. Since we have a string key
|
||||
* we can use the standard PLDHashStringEntry class as our base, it will handle
|
||||
* the key stuff for us automatically.
|
||||
*
|
||||
* #include "nsDoubleHashtable.h"
|
||||
*
|
||||
* // Do NOT ADD VIRTUAL METHODS INTO YOUR ENTRY. Everything will break.
|
||||
* // This is because of the 4-byte pointer C++ magically prepends onto your
|
||||
* // entry class. It interacts very unhappily with PLDHashTable.
|
||||
* class DictionaryEntry : public PLDHashStringEntry {
|
||||
* public:
|
||||
* DictionaryEntry(const void* aKey) : PLDHashStringEntry(aKey) { }
|
||||
* ~DictionaryEntry() { }
|
||||
* nsString mPronunciation;
|
||||
* nsString mDefinition;
|
||||
* }
|
||||
*
|
||||
* (2) Create the hash class
|
||||
*
|
||||
* The final hash class you will use in step 3 is defined by 2 macros.
|
||||
*
|
||||
* DECL_DHASH_WRAPPER(Dictionary, DictionaryEntry, const nsAString&)
|
||||
* DHASH_WRAPPER(Dictionary, DictionaryEntry, const nsAString&)
|
||||
*
|
||||
* (3) Use the hash class
|
||||
*
|
||||
* Here is a simple main() that might look up a string:
|
||||
*
|
||||
* int main(void) {
|
||||
* Dictionary d;
|
||||
* nsresult rv = d.Init(10);
|
||||
* if (NS_FAILED(rv)) return 1;
|
||||
*
|
||||
* // Put an entry
|
||||
* DictionaryEntry* a = d.AddEntry(NS_LITERAL_STRING("doomed"));
|
||||
* if (!a) return 1;
|
||||
* a->mDefinition.AssignLiteral("The state you get in when a Mozilla release is pending");
|
||||
* a->mPronunciation.AssignLiteral("doom-d");
|
||||
*
|
||||
* // Get the entry
|
||||
* DictionaryEntry* b = d.GetEntry(NS_LITERAL_STRING("doomed"));
|
||||
* printf("doomed: %s\n", NS_ConvertUTF16toUTF8(b->mDefinition).get());
|
||||
*
|
||||
* // Entries will be automagically cleaned up when the Dictionary object goes away
|
||||
* return 0;
|
||||
* }
|
||||
*
|
||||
*
|
||||
* BONUS POINTS
|
||||
*
|
||||
* You may wish to extend this class and add helper functions like
|
||||
* nsDependentString* GetDefinition(nsAString& aWord). For example:
|
||||
*
|
||||
* class MyDictionary : public Dictionary {
|
||||
* public:
|
||||
* MyDictionary() { }
|
||||
* // Make SURE you have a virtual destructor
|
||||
* virtual ~myDictionary() { }
|
||||
* nsDependentString* GetDefinition(const nsAString& aWord) {
|
||||
* DictionaryEntry* e = GetEntry(aWord);
|
||||
* if (e) {
|
||||
* // We're returning an nsDependentString here, callers need to delete it
|
||||
* // and it doesn't last long, but at least it doesn't create a copy
|
||||
* return new nsDependentString(e->mDefinition.get());
|
||||
* } else {
|
||||
* return nsnull;
|
||||
* }
|
||||
* }
|
||||
* nsresult PutDefinition(const nsAString& aWord,
|
||||
* const nsAString& aDefinition,
|
||||
* const nsAString& aPronunciation) {
|
||||
* DictionaryEntry* e = AddEntry(aWord);
|
||||
* if (!e) {
|
||||
* return NS_ERROR_OUT_OF_MEMORY;
|
||||
* }
|
||||
* e->mDefinition = aDefinition;
|
||||
* e->mPronunciation = aPronunciation;
|
||||
* return NS_OK;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* ENTRY CLASS DEFINITION
|
||||
*
|
||||
* The simplifications of PLDHashTable all hinge upon the idea of an entry
|
||||
* class, which is a class you define, where you store the key and values that
|
||||
* you will place in each hash entry. You must define six methods for an entry
|
||||
* (the standard key classes, which you can extend from, define all of these
|
||||
* for you except the constructor and destructor):
|
||||
*
|
||||
* CONSTRUCTOR(const void* aKey)
|
||||
* When your entry is constructed it will only be given a pointer to the key.
|
||||
*
|
||||
* DESTRUCTOR
|
||||
* Called when the entry is destroyed (of course).
|
||||
*
|
||||
* bool MatchEntry(const void* aKey) - return true or false depending on
|
||||
* whether the key pointed to by aKey matches this entry
|
||||
*
|
||||
* static PLDHashNumber HashKey(const void* aKey) - get a hashcode based on the
|
||||
* key (must be the same every time for the same key, but does not have
|
||||
* to be unique)
|
||||
*
|
||||
* For a small hash that just does key->value, you will often just extend a
|
||||
* standard key class and put a value member into it, and have a destructor and
|
||||
* constructor--nothing else necessary.
|
||||
*
|
||||
* See the default key entry classes as example entry classes.
|
||||
*
|
||||
* NOTES:
|
||||
* - Do NOT ADD VIRTUAL METHODS INTO YOUR ENTRY. Everything will break.
|
||||
* This is because of the 4-byte pointer C++ magically prepends onto your
|
||||
* entry class. It interacts very unhappily with PLDHashTable.
|
||||
*/
|
||||
|
||||
/*
|
||||
* PRIVATE HASHTABLE MACROS
|
||||
*
|
||||
* These internal macros can be used to declare the callbacks for an entry
|
||||
* class, but the wrapper class macros call these for you so don't call them.
|
||||
*/
|
||||
|
||||
//
|
||||
// DHASH_CALLBACKS
|
||||
//
|
||||
// Define the hashtable callback functions. Do this in one place only, as you
|
||||
// will have redundant symbols otherwise.
|
||||
//
|
||||
// ENTRY_CLASS: the classname of the entry
|
||||
//
|
||||
#define DHASH_CALLBACKS(ENTRY_CLASS) \
|
||||
static PLDHashNumber \
|
||||
ENTRY_CLASS##HashKey(PLDHashTable* table, const void* key) \
|
||||
{ \
|
||||
return ENTRY_CLASS::HashKey(key); \
|
||||
} \
|
||||
static bool \
|
||||
ENTRY_CLASS##MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *entry, \
|
||||
const void *key) \
|
||||
{ \
|
||||
const ENTRY_CLASS* e = static_cast<const ENTRY_CLASS*>(entry); \
|
||||
return e->MatchEntry(key); \
|
||||
} \
|
||||
static void \
|
||||
ENTRY_CLASS##ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry) \
|
||||
{ \
|
||||
ENTRY_CLASS* e = static_cast<ENTRY_CLASS *>(entry); \
|
||||
e->~ENTRY_CLASS(); \
|
||||
} \
|
||||
static bool \
|
||||
ENTRY_CLASS##InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry, \
|
||||
const void *key) \
|
||||
{ \
|
||||
new (entry) ENTRY_CLASS(key); \
|
||||
return true; \
|
||||
}
|
||||
|
||||
//
|
||||
// DHASH_INIT
|
||||
//
|
||||
// Initialize hashtable to a certain class.
|
||||
//
|
||||
// HASHTABLE: the name of the PLDHashTable variable
|
||||
// ENTRY_CLASS: the classname of the entry
|
||||
// NUM_INITIAL_ENTRIES: the number of entry slots the hashtable should start
|
||||
// with
|
||||
// RV: an nsresult variable to hold the outcome of the initialization.
|
||||
// Will be NS_ERROR_OUT_OF_MEMORY if failed, NS_OK otherwise.
|
||||
//
|
||||
#define DHASH_INIT(HASHTABLE,ENTRY_CLASS,NUM_INITIAL_ENTRIES,RV) \
|
||||
PR_BEGIN_MACRO \
|
||||
static PLDHashTableOps hash_table_ops = \
|
||||
{ \
|
||||
PL_DHashAllocTable, \
|
||||
PL_DHashFreeTable, \
|
||||
ENTRY_CLASS##HashKey, \
|
||||
ENTRY_CLASS##MatchEntry, \
|
||||
PL_DHashMoveEntryStub, \
|
||||
ENTRY_CLASS##ClearEntry, \
|
||||
PL_DHashFinalizeStub, \
|
||||
ENTRY_CLASS##InitEntry \
|
||||
}; \
|
||||
bool isLive = PL_DHashTableInit(&(HASHTABLE), \
|
||||
&hash_table_ops, nsnull, \
|
||||
sizeof(ENTRY_CLASS), \
|
||||
(NUM_INITIAL_ENTRIES)); \
|
||||
if (!isLive) { \
|
||||
(HASHTABLE).ops = nsnull; \
|
||||
RV = NS_ERROR_OUT_OF_MEMORY; \
|
||||
} else { \
|
||||
RV = NS_OK; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
|
||||
/*
|
||||
* WRAPPER CLASS
|
||||
*
|
||||
* This class handles initialization and destruction of the hashtable
|
||||
* (you must call Init() yourself). It defines these functions:
|
||||
*
|
||||
* Init(aNumInitialEntries)
|
||||
* Initialize the hashtable. This must be called once, it is only separate
|
||||
* from the constructor so that you can get the return value. You should pass
|
||||
* in the number of entries you think the hashtable will typically hold (this
|
||||
* will be the amount of space allocated initially so that it will not have to
|
||||
* grow).
|
||||
*
|
||||
* ENTRY_CLASS* GetEntry(aKey):
|
||||
* Get the entry referenced by aKey and return a pointer to it. THIS IS A
|
||||
* TEMPORARY POINTER and is only guaranteed to exist until the next time you do
|
||||
* an operation on the hashtable. But you can safely use it until then.
|
||||
*
|
||||
* Returns nsnull if the entry is not found.
|
||||
*
|
||||
* ENTRY_CLASS* AddEntry(aKey):
|
||||
* Create a new, empty entry and return a pointer to it for you to fill values
|
||||
* into. THIS IS A TEMPORARY POINTER and is only guaranteed to exist until the
|
||||
* next time you do an operation on the hashtable. But you can safely fill it
|
||||
* in.
|
||||
*
|
||||
* Returns nsnull if the entry cannot be created (usually a low memory
|
||||
* constraint).
|
||||
*
|
||||
* void Remove(aKey)
|
||||
* Remove the entry referenced by aKey. If the entry does not exist, nothing
|
||||
* will happen.
|
||||
*
|
||||
*
|
||||
* DECL_DHASH_WRAPPER(CLASSNAME,ENTRY_CLASS,KEY_TYPE)
|
||||
*
|
||||
* Declare the hash class but do not define the functions.
|
||||
*
|
||||
* CLASSNAME: the name of the class to declare.
|
||||
* ENTRY_CLASS: the class of the entry struct.
|
||||
* KEY_TYPE: the name of the key type for GetEntry and AddEntry.
|
||||
*
|
||||
*
|
||||
* DHASH_WRAPPER(CLASSNAME,ENTRY_CLASS,KEY_TYPE)
|
||||
*
|
||||
* Define the functions for the hash class.
|
||||
*
|
||||
* CLASSNAME: the name of the class to declare.
|
||||
* ENTRY_CLASS: the class of the entry struct.
|
||||
* KEY_TYPE: the name of the key type for GetEntry and AddEntry.
|
||||
*
|
||||
*
|
||||
* CAVEATS:
|
||||
* - You may have only *one* wrapper class per entry class.
|
||||
*/
|
||||
|
||||
#define DECL_DHASH_WRAPPER(CLASSNAME,ENTRY_CLASS,KEY_TYPE) \
|
||||
class DHASH_EXPORT CLASSNAME { \
|
||||
public: \
|
||||
CLASSNAME(); \
|
||||
~CLASSNAME(); \
|
||||
nsresult Init(PRUint32 aNumInitialEntries); \
|
||||
ENTRY_CLASS* GetEntry(const KEY_TYPE aKey); \
|
||||
ENTRY_CLASS* AddEntry(const KEY_TYPE aKey); \
|
||||
void Remove(const KEY_TYPE aKey); \
|
||||
PLDHashTable mHashTable; \
|
||||
};
|
||||
|
||||
#define DHASH_WRAPPER(CLASSNAME,ENTRY_CLASS,KEY_TYPE) \
|
||||
DHASH_CALLBACKS(ENTRY_CLASS) \
|
||||
CLASSNAME::CLASSNAME() { \
|
||||
mHashTable.ops = nsnull; \
|
||||
} \
|
||||
CLASSNAME::~CLASSNAME() { \
|
||||
if (mHashTable.ops) { \
|
||||
PL_DHashTableFinish(&mHashTable); \
|
||||
} \
|
||||
} \
|
||||
nsresult CLASSNAME::Init(PRUint32 aNumInitialEntries) { \
|
||||
if (!mHashTable.ops) { \
|
||||
nsresult rv; \
|
||||
DHASH_INIT(mHashTable,ENTRY_CLASS,aNumInitialEntries,rv); \
|
||||
return rv; \
|
||||
} \
|
||||
return NS_OK; \
|
||||
} \
|
||||
ENTRY_CLASS* CLASSNAME::GetEntry(const KEY_TYPE aKey) { \
|
||||
ENTRY_CLASS* e = static_cast<ENTRY_CLASS*>( \
|
||||
PL_DHashTableOperate(&mHashTable, &aKey, \
|
||||
PL_DHASH_LOOKUP)); \
|
||||
return PL_DHASH_ENTRY_IS_BUSY(e) ? e : nsnull; \
|
||||
} \
|
||||
ENTRY_CLASS* CLASSNAME::AddEntry(const KEY_TYPE aKey) { \
|
||||
return static_cast<ENTRY_CLASS*>( \
|
||||
PL_DHashTableOperate(&mHashTable, &aKey, \
|
||||
PL_DHASH_ADD)); \
|
||||
} \
|
||||
void CLASSNAME::Remove(const KEY_TYPE aKey) { \
|
||||
PL_DHashTableOperate(&mHashTable, &aKey, PL_DHASH_REMOVE); \
|
||||
}
|
||||
|
||||
/*
|
||||
* STANDARD KEY ENTRY CLASSES
|
||||
*
|
||||
* We have declared some standard key classes for you to make life a little
|
||||
* easier. These include string, int and void* keys. You can extend these
|
||||
* and add value data members to make a working hash entry class with your
|
||||
* values.
|
||||
*
|
||||
* PLDHashStringEntry: nsAString
|
||||
* PLDHashCStringEntry: nsACString
|
||||
* PLDHashInt32Entry: PRInt32
|
||||
* PLDHashVoidEntry: void*
|
||||
*
|
||||
* As a short example, if you want to make a class that maps int to string,
|
||||
* you could do:
|
||||
*
|
||||
* class MyIntStringEntry : public PLDHashInt32Entry
|
||||
* {
|
||||
* public:
|
||||
* MyIntStringEntry(const void* aKey) : PLDHashInt32Entry(aKey) { }
|
||||
* ~MyIntStringEntry() { };
|
||||
* nsString mMyStr;
|
||||
* };
|
||||
*
|
||||
* XXX It could be advisable (unless COW strings ever happens) to have a
|
||||
* PLDHashDependentStringEntry
|
||||
*/
|
||||
|
||||
//
|
||||
// String-key entry
|
||||
//
|
||||
class PLDHashStringEntry : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
PLDHashStringEntry(const void* aKey) :
|
||||
mKey(*static_cast<const nsAString*>(aKey)) { }
|
||||
~PLDHashStringEntry() { }
|
||||
|
||||
static PLDHashNumber HashKey(const void* key) {
|
||||
return HashString(*static_cast<const nsAString*>(key));
|
||||
}
|
||||
bool MatchEntry(const void* key) const {
|
||||
return static_cast<const nsAString*>(key)->Equals(mKey);
|
||||
}
|
||||
|
||||
const nsString mKey;
|
||||
};
|
||||
|
||||
//
|
||||
// CString-key entry
|
||||
//
|
||||
class PLDHashCStringEntry : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
PLDHashCStringEntry(const void* aKey) :
|
||||
mKey(*static_cast<const nsACString*>(aKey)) { }
|
||||
~PLDHashCStringEntry() { }
|
||||
|
||||
static PLDHashNumber HashKey(const void* key) {
|
||||
return HashString(*static_cast<const nsACString*>(key));
|
||||
}
|
||||
bool MatchEntry(const void* key) const {
|
||||
return static_cast<const nsACString*>(key)->Equals(mKey);
|
||||
}
|
||||
|
||||
const nsCString mKey;
|
||||
};
|
||||
|
||||
//
|
||||
// Int-key entry
|
||||
//
|
||||
class PLDHashInt32Entry : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
PLDHashInt32Entry(const void* aKey) :
|
||||
mKey(*(static_cast<const PRInt32*>(aKey))) { }
|
||||
~PLDHashInt32Entry() { }
|
||||
|
||||
static PLDHashNumber HashKey(const void* key) {
|
||||
return *static_cast<const PRInt32*>(key);
|
||||
}
|
||||
bool MatchEntry(const void* key) const {
|
||||
return *(static_cast<const PRInt32*>(key)) == mKey;
|
||||
}
|
||||
|
||||
const PRInt32 mKey;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Void-key entry
|
||||
//
|
||||
class PLDHashVoidEntry : public PLDHashEntryHdr
|
||||
{
|
||||
public:
|
||||
PLDHashVoidEntry(const void* aKey) :
|
||||
mKey(*(const void**)aKey) { }
|
||||
~PLDHashVoidEntry() { }
|
||||
|
||||
static PLDHashNumber HashKey(const void* key) {
|
||||
return PLDHashNumber(NS_PTR_TO_INT32(*(const void**)key)) >> 2;
|
||||
}
|
||||
bool MatchEntry(const void* key) const {
|
||||
return *(const void**)key == mKey;
|
||||
}
|
||||
|
||||
const void* mKey;
|
||||
};
|
||||
|
||||
|
||||
#define DHASH_EXPORT
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user