Bug 114882. Hash integer and date literals, as well. Convert all hashtables to use dhash. r=tingley, sr=hyatt.

This commit is contained in:
waterson%netscape.com 2001-12-20 23:04:33 +00:00
Родитель d9bc74de4c
Коммит 1618846cfd
1 изменённых файлов: 442 добавлений и 209 удалений

Просмотреть файл

@ -60,6 +60,7 @@
#include "nsString.h"
#include "nsWeakReference.h"
#include "nsXPIDLString.h"
#include "pldhash.h"
#include "plhash.h"
#include "plstr.h"
#include "prlog.h"
@ -84,12 +85,6 @@ static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static PRLogModuleInfo* gLog = nsnull;
#endif
// Defining these will re-use the string pointer that is owned by the
// resource (or literal) as the key for the hashtable. It avoids two
// strdup()'s for each new resource that is created.
#define REUSE_RESOURCE_URI_AS_KEY
#define REUSE_LITERAL_VALUE_AS_KEY
////////////////////////////////////////////////////////////////////////
// RDFServiceImpl
//
@ -100,8 +95,10 @@ class RDFServiceImpl : public nsIRDFService,
{
protected:
PLHashTable* mNamedDataSources;
PLHashTable* mResources;
PLHashTable* mLiterals;
PLDHashTable mResources;
PLDHashTable mLiterals;
PLDHashTable mInts;
PLDHashTable mDates;
char mLastURIPrefix[16];
PRInt32 mLastPrefixlen;
@ -123,8 +120,13 @@ public:
NS_DECL_NSIRDFSERVICE
// Implementation methods
nsresult RegisterLiteral(nsIRDFLiteral* aLiteral, PRBool aReplace = PR_FALSE);
nsresult RegisterLiteral(nsIRDFLiteral* aLiteral);
nsresult UnregisterLiteral(nsIRDFLiteral* aLiteral);
nsresult RegisterInt(nsIRDFInt* aInt);
nsresult UnregisterInt(nsIRDFInt* aInt);
nsresult RegisterDate(nsIRDFDate* aDate);
nsresult UnregisterDate(nsIRDFDate* aDate);
nsresult GetDataSource(const char *aURI, PRBool aBlock, nsIRDFDataSource **aDataSource );
};
@ -133,6 +135,7 @@ static RDFServiceImpl* gRDFService; // The one-and-only RDF service
// These functions are copied from nsprpub/lib/ds/plhash.c, with one
// change to free the key in DataSourceFreeEntry.
// XXX sigh, why were DefaultAllocTable et. al. declared static, anyway?
static void * PR_CALLBACK
DataSourceAllocTable(void *pool, PRSize size)
@ -182,6 +185,196 @@ static PLHashAllocOps dataSourceHashAllocOps = {
DataSourceAllocEntry, DataSourceFreeEntry
};
//----------------------------------------------------------------------
//
// For the mResources hashtable.
//
struct ResourceHashEntry : public PLDHashEntryHdr {
const char *mKey;
nsIRDFResource *mResource;
static const void * PR_CALLBACK
GetKey(PLDHashTable *table, PLDHashEntryHdr *hdr)
{
ResourceHashEntry *entry = NS_STATIC_CAST(ResourceHashEntry *, hdr);
return entry->mKey;
}
static PLDHashNumber PR_CALLBACK
HashKey(PLDHashTable *table, const void *key)
{
return nsCRT::HashCode(NS_STATIC_CAST(const char *, key));
}
static PRBool PR_CALLBACK
MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
const void *key)
{
const ResourceHashEntry *entry =
NS_STATIC_CAST(const ResourceHashEntry *, hdr);
return 0 == nsCRT::strcmp(NS_STATIC_CAST(const char *, key),
entry->mKey);
}
};
static PLDHashTableOps gResourceTableOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
ResourceHashEntry::GetKey,
ResourceHashEntry::HashKey,
ResourceHashEntry::MatchEntry,
PL_DHashMoveEntryStub,
PL_DHashClearEntryStub,
PL_DHashFinalizeStub,
nsnull
};
// ----------------------------------------------------------------------
//
// For the mLiterals hashtable.
//
struct LiteralHashEntry : public PLDHashEntryHdr {
nsIRDFLiteral *mLiteral;
const PRUnichar *mKey;
static const void * PR_CALLBACK
GetKey(PLDHashTable *table, PLDHashEntryHdr *hdr)
{
LiteralHashEntry *entry = NS_STATIC_CAST(LiteralHashEntry *, hdr);
return entry->mKey;
}
static PLDHashNumber PR_CALLBACK
HashKey(PLDHashTable *table, const void *key)
{
return nsCRT::HashCode(NS_STATIC_CAST(const PRUnichar *, key));
}
static PRBool PR_CALLBACK
MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
const void *key)
{
const LiteralHashEntry *entry =
NS_STATIC_CAST(const LiteralHashEntry *, hdr);
return 0 == nsCRT::strcmp(NS_STATIC_CAST(const PRUnichar *, key),
entry->mKey);
}
};
static PLDHashTableOps gLiteralTableOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
LiteralHashEntry::GetKey,
LiteralHashEntry::HashKey,
LiteralHashEntry::MatchEntry,
PL_DHashMoveEntryStub,
PL_DHashClearEntryStub,
PL_DHashFinalizeStub,
nsnull
};
// ----------------------------------------------------------------------
//
// For the mInts hashtable.
//
struct IntHashEntry : public PLDHashEntryHdr {
nsIRDFInt *mInt;
PRInt32 mKey;
static const void * PR_CALLBACK
GetKey(PLDHashTable *table, PLDHashEntryHdr *hdr)
{
IntHashEntry *entry = NS_STATIC_CAST(IntHashEntry *, hdr);
return &entry->mKey;
}
static PLDHashNumber PR_CALLBACK
HashKey(PLDHashTable *table, const void *key)
{
return PLDHashNumber(*NS_STATIC_CAST(const PRInt32 *, key));
}
static PRBool PR_CALLBACK
MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
const void *key)
{
const IntHashEntry *entry =
NS_STATIC_CAST(const IntHashEntry *, hdr);
return *NS_STATIC_CAST(const PRInt32 *, key) == entry->mKey;
}
};
static PLDHashTableOps gIntTableOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
IntHashEntry::GetKey,
IntHashEntry::HashKey,
IntHashEntry::MatchEntry,
PL_DHashMoveEntryStub,
PL_DHashClearEntryStub,
PL_DHashFinalizeStub,
nsnull
};
// ----------------------------------------------------------------------
//
// For the mDates hashtable.
//
struct DateHashEntry : public PLDHashEntryHdr {
nsIRDFDate *mDate;
PRTime mKey;
static const void * PR_CALLBACK
GetKey(PLDHashTable *table, PLDHashEntryHdr *hdr)
{
DateHashEntry *entry = NS_STATIC_CAST(DateHashEntry *, hdr);
return &entry->mKey;
}
static PLDHashNumber PR_CALLBACK
HashKey(PLDHashTable *table, const void *key)
{
// xor the low 32 bits with the high 32 bits.
PRTime t = *NS_STATIC_CAST(const PRTime *, key);
PRInt64 h64, l64;
LL_USHR(h64, t, 32);
l64 = LL_INIT(0, 0xffffffff);
LL_AND(l64, l64, t);
PRInt32 h32, l32;
LL_L2I(h32, h64);
LL_L2I(l32, l64);
return PLDHashNumber(l32 ^ h32);
}
static PRBool PR_CALLBACK
MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr,
const void *key)
{
const DateHashEntry *entry =
NS_STATIC_CAST(const DateHashEntry *, hdr);
return LL_EQ(*NS_STATIC_CAST(const PRTime *, key), entry->mKey);
}
};
static PLDHashTableOps gDateTableOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
DateHashEntry::GetKey,
DateHashEntry::HashKey,
DateHashEntry::MatchEntry,
PL_DHashMoveEntryStub,
PL_DHashClearEntryStub,
PL_DHashFinalizeStub,
nsnull
};
////////////////////////////////////////////////////////////////////////
// LiteralImpl
@ -244,11 +437,6 @@ LiteralImpl::LiteralImpl(const PRUnichar* s)
LiteralImpl::~LiteralImpl()
{
#ifdef DEBUG_REFS
--gInstanceCount;
fprintf(stdout, "%d - RDF: LiteralImpl\n", gInstanceCount);
#endif
gRDFService->UnregisterLiteral(this);
// Use NS_RELEASE2() here, because we want to decrease the
@ -346,14 +534,19 @@ DateImpl::DateImpl(const PRTime s)
: mValue(s)
{
NS_INIT_REFCNT();
gRDFService->RegisterDate(this);
NS_ADDREF(gRDFService);
}
DateImpl::~DateImpl()
{
#ifdef DEBUG_REFS
--gInstanceCount;
fprintf(stdout, "%d - RDF: DateImpl\n", gInstanceCount);
#endif
gRDFService->UnregisterDate(this);
// Use NS_RELEASE2() here, because we want to decrease the
// refcount, but not null out the gRDFService pointer (which is
// what a vanilla NS_RELEASE() would do).
nsrefcnt refcnt;
NS_RELEASE2(gRDFService, refcnt);
}
NS_IMPL_ADDREF(DateImpl);
@ -448,14 +641,19 @@ IntImpl::IntImpl(PRInt32 s)
: mValue(s)
{
NS_INIT_REFCNT();
gRDFService->RegisterInt(this);
NS_ADDREF(gRDFService);
}
IntImpl::~IntImpl()
{
#ifdef DEBUG_REFS
--gInstanceCount;
fprintf(stdout, "%d - RDF: IntImpl\n", gInstanceCount);
#endif
gRDFService->UnregisterInt(this);
// Use NS_RELEASE2() here, because we want to decrease the
// refcount, but not null out the gRDFService pointer (which is
// what a vanilla NS_RELEASE() would do).
nsrefcnt refcnt;
NS_RELEASE2(gRDFService, refcnt);
}
NS_IMPL_ADDREF(IntImpl);
@ -525,58 +723,38 @@ IntImpl::EqualsInt(nsIRDFInt* intValue, PRBool* result)
////////////////////////////////////////////////////////////////////////
// RDFServiceImpl
static PLHashNumber PR_CALLBACK
rdf_HashWideString(const void* key)
{
PLHashNumber result = 0;
for (PRUnichar* s = (PRUnichar*) key; *s != nsnull; ++s)
result = (result >> 28) ^ (result << 4) ^ *s;
return result;
}
static PRIntn PR_CALLBACK
rdf_CompareWideStrings(const void* v1, const void* v2)
{
return 0 == nsCRT::strcmp(NS_STATIC_CAST(const PRUnichar*, v1), NS_STATIC_CAST(const PRUnichar*, v2));
}
RDFServiceImpl::RDFServiceImpl()
: mNamedDataSources(nsnull), mResources(nsnull), mLiterals(nsnull), mLastPrefixlen(0)
: mNamedDataSources(nsnull),
mLastPrefixlen(0)
{
NS_INIT_REFCNT();
}
nsresult
RDFServiceImpl::Init()
{
nsresult rv;
mResources = PL_NewHashTable(1023, // nbuckets
PL_HashString, // hash fn
PL_CompareStrings, // key compare fn
PL_CompareValues, // value compare fn
nsnull, nsnull); // alloc ops & priv
if (! mResources) return NS_ERROR_OUT_OF_MEMORY;
mLiterals = PL_NewHashTable(1023,
rdf_HashWideString,
rdf_CompareWideStrings,
PL_CompareValues,
nsnull, nsnull);
if (! mLiterals) return NS_ERROR_OUT_OF_MEMORY;
mNamedDataSources = PL_NewHashTable(23,
PL_HashString,
PL_CompareStrings,
PL_CompareValues,
&dataSourceHashAllocOps, nsnull);
if (! mNamedDataSources) return NS_ERROR_OUT_OF_MEMORY;
if (! mNamedDataSources)
return NS_ERROR_OUT_OF_MEMORY;
PL_DHashTableInit(&mResources, &gResourceTableOps, nsnull,
sizeof(ResourceHashEntry), PL_DHASH_MIN_SIZE);
PL_DHashTableInit(&mLiterals, &gLiteralTableOps, nsnull,
sizeof(LiteralHashEntry), PL_DHASH_MIN_SIZE);
PL_DHashTableInit(&mInts, &gIntTableOps, nsnull,
sizeof(IntHashEntry), PL_DHASH_MIN_SIZE);
PL_DHashTableInit(&mDates, &gDateTableOps, nsnull,
sizeof(DateHashEntry), PL_DHASH_MIN_SIZE);
rv = nsComponentManager::FindFactory(kRDFDefaultResourceCID, getter_AddRefs(mDefaultResourceFactory));
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get default resource factory");
@ -593,23 +771,14 @@ RDFServiceImpl::Init()
RDFServiceImpl::~RDFServiceImpl()
{
#ifdef DEBUG_REFS
--gInstanceCount;
fprintf(stdout, "%d - RDF: RDFServiceImpl\n", gInstanceCount);
#endif
if (mNamedDataSources) {
PL_HashTableDestroy(mNamedDataSources);
mNamedDataSources = nsnull;
}
if (mResources) {
PL_HashTableDestroy(mResources);
mResources = nsnull;
}
if (mLiterals) {
PL_HashTableDestroy(mLiterals);
mLiterals = nsnull;
}
PL_DHashTableFinish(&mResources);
PL_DHashTableFinish(&mLiterals);
PL_DHashTableFinish(&mInts);
PL_DHashTableFinish(&mDates);
gRDFService = nsnull;
}
@ -691,13 +860,12 @@ RDFServiceImpl::GetResource(const char* aURI, nsIRDFResource** aResource)
// First, check the cache to see if we've already created and
// registered this thing.
nsIRDFResource* result =
NS_STATIC_CAST(nsIRDFResource*, PL_HashTableLookup(mResources, aURI));
PLDHashEntryHdr *hdr =
PL_DHashTableOperate(&mResources, aURI, PL_DHASH_LOOKUP);
if (result) {
// Addref for the callee.
NS_ADDREF(result);
*aResource = result;
if (PL_DHASH_ENTRY_IS_BUSY(hdr)) {
ResourceHashEntry *entry = NS_STATIC_CAST(ResourceHashEntry *, hdr);
NS_ADDREF(*aResource = entry->mResource);
return NS_OK;
}
@ -789,6 +957,7 @@ RDFServiceImpl::GetResource(const char* aURI, nsIRDFResource** aResource)
}
}
nsIRDFResource *result;
rv = factory->CreateInstance(nsnull, NS_GET_IID(nsIRDFResource), (void**) &result);
if (NS_FAILED(rv)) return rv;
@ -890,13 +1059,13 @@ RDFServiceImpl::GetLiteral(const PRUnichar* aValue, nsIRDFLiteral** aLiteral)
if (! aLiteral)
return NS_ERROR_NULL_POINTER;
// See if we have on already cached
nsIRDFLiteral* literal =
NS_STATIC_CAST(nsIRDFLiteral*, PL_HashTableLookup(mLiterals, aValue));
// See if we have one already cached
PLDHashEntryHdr *hdr =
PL_DHashTableOperate(&mLiterals, aValue, PL_DHASH_LOOKUP);
if (literal) {
NS_ADDREF(literal);
*aLiteral = literal;
if (PL_DHASH_ENTRY_IS_BUSY(hdr)) {
LiteralHashEntry *entry = NS_STATIC_CAST(LiteralHashEntry *, hdr);
NS_ADDREF(*aLiteral = entry->mLiteral);
return NS_OK;
}
@ -905,32 +1074,47 @@ RDFServiceImpl::GetLiteral(const PRUnichar* aValue, nsIRDFLiteral** aLiteral)
}
NS_IMETHODIMP
RDFServiceImpl::GetDateLiteral(PRTime time, nsIRDFDate** literal)
RDFServiceImpl::GetDateLiteral(PRTime aTime, nsIRDFDate** aResult)
{
// XXX how do we cache these? should they live in their own hashtable?
DateImpl* result = new DateImpl(time);
// See if we have one already cached
PLDHashEntryHdr *hdr =
PL_DHashTableOperate(&mDates, &aTime, PL_DHASH_LOOKUP);
if (PL_DHASH_ENTRY_IS_BUSY(hdr)) {
DateHashEntry *entry = NS_STATIC_CAST(DateHashEntry *, hdr);
NS_ADDREF(*aResult = entry->mDate);
return NS_OK;
}
DateImpl* result = new DateImpl(aTime);
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
*literal = result;
NS_ADDREF(result);
NS_ADDREF(*aResult = result);
return NS_OK;
}
NS_IMETHODIMP
RDFServiceImpl::GetIntLiteral(PRInt32 value, nsIRDFInt** literal)
RDFServiceImpl::GetIntLiteral(PRInt32 aInt, nsIRDFInt** aResult)
{
// XXX how do we cache these? should they live in their own hashtable?
IntImpl* result = new IntImpl(value);
// See if we have one already cached
PLDHashEntryHdr *hdr =
PL_DHashTableOperate(&mInts, &aInt, PL_DHASH_LOOKUP);
if (PL_DHASH_ENTRY_IS_BUSY(hdr)) {
IntHashEntry *entry = NS_STATIC_CAST(IntHashEntry *, hdr);
NS_ADDREF(*aResult = entry->mInt);
return NS_OK;
}
IntImpl* result = new IntImpl(aInt);
if (! result)
return NS_ERROR_OUT_OF_MEMORY;
*literal = result;
NS_ADDREF(result);
NS_ADDREF(*aResult = result);
return NS_OK;
}
NS_IMETHODIMP
RDFServiceImpl::IsAnonymousResource(nsIRDFResource* aResource, PRBool* _result)
{
@ -968,13 +1152,8 @@ RDFServiceImpl::RegisterResource(nsIRDFResource* aResource, PRBool aReplace)
nsresult rv;
#ifdef REUSE_RESOURCE_URI_AS_KEY
const char* uri;
rv = aResource->GetValueConst(&uri);
#else
nsXPIDLCString uri;
rv = aResource->GetValue(getter_Copies(uri));
#endif
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get URI from resource");
if (NS_FAILED(rv)) return rv;
@ -982,10 +1161,10 @@ RDFServiceImpl::RegisterResource(nsIRDFResource* aResource, PRBool aReplace)
if (! uri)
return NS_ERROR_NULL_POINTER;
PLHashNumber keyhash = (*mResources->keyHash)(uri);
PLHashEntry** hep = PL_HashTableRawLookup(mResources, keyhash, uri);
PLDHashEntryHdr *hdr =
PL_DHashTableOperate(&mResources, uri, PL_DHASH_LOOKUP);
if (*hep) {
if (PL_DHASH_ENTRY_IS_BUSY(hdr)) {
if (!aReplace) {
NS_WARNING("resource already registered, and replace not specified");
return NS_ERROR_FAILURE; // already registered
@ -997,34 +1176,27 @@ RDFServiceImpl::RegisterResource(nsIRDFResource* aResource, PRBool aReplace)
PR_LOG(gLog, PR_LOG_DEBUG,
("rdfserv replace-resource [%p] <-- [%p] %s",
(*hep)->value, aResource, (const char*) uri));
#ifdef REUSE_RESOURCE_URI_AS_KEY
(*hep)->key = uri;
#endif
(*hep)->value = aResource;
NS_STATIC_CAST(ResourceHashEntry *, hdr)->mResource,
aResource, (const char*) uri));
}
else {
#ifdef REUSE_RESOURCE_URI_AS_KEY
PL_HashTableRawAdd(mResources, hep, keyhash, uri, aResource);
#else
const char* key = PL_strdup(uri);
if (! key)
hdr = PL_DHashTableOperate(&mResources, uri, PL_DHASH_ADD);
if (! hdr)
return NS_ERROR_OUT_OF_MEMORY;
PL_HashTableRawAdd(mResources, hep, keyhash, key, aResource);
#endif
PR_LOG(gLog, PR_LOG_DEBUG,
("rdfserv register-resource [%p] %s",
aResource, (const char*) uri));
// N.B., we only hold a weak reference to the resource: that
// way, the resource can be destroyed when the last refcount
// goes away. The single addref that the CreateResource() call
// made will be owned by the callee.
}
// N.B., we only hold a weak reference to the resource: that way,
// the resource can be destroyed when the last refcount goes
// away. The single addref that the CreateResource() call made
// will be owned by the callee.
ResourceHashEntry *entry = NS_STATIC_CAST(ResourceHashEntry *, hdr);
entry->mResource = aResource;
entry->mKey = uri;
return NS_OK;
}
@ -1037,35 +1209,24 @@ RDFServiceImpl::UnregisterResource(nsIRDFResource* aResource)
nsresult rv;
#ifdef REUSE_RESOURCE_URI_AS_KEY
const char* uri;
rv = aResource->GetValueConst(&uri);
#else
nsXPIDLCString uri;
rv = aResource->GetValue(getter_Copies(uri));
#endif
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(uri != nsnull, "resource has no URI");
if (! uri)
return NS_ERROR_UNEXPECTED;
PLHashEntry** hep = PL_HashTableRawLookup(mResources, (*mResources->keyHash)(uri), uri);
if (!hep || !*hep)
return NS_OK;
#ifndef REUSE_RESOURCE_URI_AS_KEY
PL_strfree((char*) (*hep)->key);
#endif
// N.B. that we _don't_ release the resource: we only held a weak
// reference to it in the hashtable.
PR_LOG(gLog, PR_LOG_DEBUG,
("rdfserv unregister-resource [%p] %s",
aResource, (const char*) uri));
PL_HashTableRawRemove(mResources, hep, *hep);
#ifdef DEBUG
if (PL_DHASH_ENTRY_IS_FREE(PL_DHashTableOperate(&mResources, uri, PL_DHASH_LOOKUP)))
NS_WARNING("resource was never registered");
#endif
PL_DHashTableOperate(&mResources, uri, PL_DHASH_REMOVE);
return NS_OK;
}
@ -1249,65 +1410,34 @@ RDFServiceImpl::GetDataSource(const char* aURI, PRBool aBlock, nsIRDFDataSource*
////////////////////////////////////////////////////////////////////////
nsresult
RDFServiceImpl::RegisterLiteral(nsIRDFLiteral* aLiteral, PRBool aReplace)
RDFServiceImpl::RegisterLiteral(nsIRDFLiteral* aLiteral)
{
NS_PRECONDITION(aLiteral != nsnull, "null ptr");
if (! aLiteral)
return NS_ERROR_NULL_POINTER;
nsresult rv;
#ifdef REUSE_LITERAL_VALUE_AS_KEY
const PRUnichar* value;
rv = aLiteral->GetValueConst(&value);
#else
nsXPIDLString value;
rv = aLiteral->GetValue(getter_Copies(value));
#endif
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get literal's value");
if (NS_FAILED(rv)) return rv;
aLiteral->GetValueConst(&value);
PLHashEntry** hep = PL_HashTableRawLookup(mLiterals, (*mLiterals->keyHash)(value), value);
NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableOperate(&mLiterals,
value,
PL_DHASH_LOOKUP)),
"literal already registered");
if (*hep) {
if (! aReplace) {
NS_WARNING("literal already registered and replace not specified");
return NS_ERROR_FAILURE;
}
PLDHashEntryHdr *hdr =
PL_DHashTableOperate(&mLiterals, value, PL_DHASH_ADD);
// N.B., we do _not_ release the original literal because we
// only ever held a weak reference to it. We simply replace
// it.
if (! hdr)
return NS_ERROR_OUT_OF_MEMORY;
PR_LOG(gLog, PR_LOG_DEBUG,
("rdfserv replace-literal [%p] <-- [%p] %s",
(*hep)->value, aLiteral, (const PRUnichar*) value));
LiteralHashEntry *entry = NS_STATIC_CAST(LiteralHashEntry *, hdr);
#ifdef REUSE_LITERAL_VALUE_AS_KEY
(*hep)->key = value;
#endif
(*hep)->value = aLiteral;
}
else {
#ifdef REUSE_LITERAL_VALUE_AS_KEY
PL_HashTableAdd(mLiterals, value, aLiteral);
#else
const PRUnichar* key = value.get() ? nsCRT::strdup(value.get()) : 0;
if (! key)
return NS_ERROR_OUT_OF_MEMORY;
// N.B., we only hold a weak reference to the literal: that
// way, the literal can be destroyed when the last refcount
// goes away. The single addref that the CreateLiteral() call
// made will be owned by the callee.
entry->mLiteral = aLiteral;
entry->mKey = value;
PL_HashTableAdd(mLiterals, key, aLiteral);
#endif
PR_LOG(gLog, PR_LOG_DEBUG,
("rdfserv register-literal [%p] %s",
aLiteral, (const PRUnichar*) value));
// N.B., we only hold a weak reference to the literal: that
// way, the literal can be destroyed when the last refcount
// goes away. The single addref that the CreateLiteral() call
// made will be owned by the callee.
}
PR_LOG(gLog, PR_LOG_DEBUG,
("rdfserv register-literal [%p] %s",
aLiteral, (const PRUnichar*) value));
return NS_OK;
}
@ -1316,39 +1446,142 @@ RDFServiceImpl::RegisterLiteral(nsIRDFLiteral* aLiteral, PRBool aReplace)
nsresult
RDFServiceImpl::UnregisterLiteral(nsIRDFLiteral* aLiteral)
{
NS_PRECONDITION(aLiteral != nsnull, "null ptr");
nsresult rv;
#ifdef REUSE_LITERAL_VALUE_AS_KEY
const PRUnichar* value;
rv = aLiteral->GetValueConst(&value);
#else
nsXPIDLString value;
rv = aLiteral->GetValue(getter_Copies(value));
#endif
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get literal's value");
if (NS_FAILED(rv)) return rv;
aLiteral->GetValueConst(&value);
PLHashEntry** hep = PL_HashTableRawLookup(mLiterals, (*mLiterals->keyHash)(value), value);
if (!hep || !*hep)
return NS_OK;
NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(PL_DHashTableOperate(&mLiterals,
value,
PL_DHASH_LOOKUP)),
"literal was never registered");
#ifndef REUSE_LITERAL_VALUE_AS_KEY
nsMemory::Free((void*) (*hep)->key);
#endif
PL_DHashTableOperate(&mLiterals, value, PL_DHASH_REMOVE);
// N.B. that we _don't_ release the literal: we only held a weak
// reference to it in the hashtable.
PR_LOG(gLog, PR_LOG_DEBUG,
("rdfserv unregister-literal [%p] %s",
aLiteral, (const PRUnichar*) value));
PL_HashTableRawRemove(mLiterals, hep, *hep);
return NS_OK;
}
//----------------------------------------------------------------------
nsresult
RDFServiceImpl::RegisterInt(nsIRDFInt* aInt)
{
PRInt32 value;
aInt->GetValue(&value);
NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableOperate(&mInts,
&value,
PL_DHASH_LOOKUP)),
"int already registered");
PLDHashEntryHdr *hdr =
PL_DHashTableOperate(&mInts, &value, PL_DHASH_ADD);
if (! hdr)
return NS_ERROR_OUT_OF_MEMORY;
IntHashEntry *entry = NS_STATIC_CAST(IntHashEntry *, hdr);
// N.B., we only hold a weak reference to the literal: that
// way, the literal can be destroyed when the last refcount
// goes away. The single addref that the CreateInt() call
// made will be owned by the callee.
entry->mInt = aInt;
entry->mKey = value;
PR_LOG(gLog, PR_LOG_DEBUG,
("rdfserv register-int [%p] %d",
aInt, value));
return NS_OK;
}
nsresult
RDFServiceImpl::UnregisterInt(nsIRDFInt* aInt)
{
PRInt32 value;
aInt->GetValue(&value);
NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(PL_DHashTableOperate(&mInts,
&value,
PL_DHASH_LOOKUP)),
"int was never registered");
PL_DHashTableOperate(&mInts, &value, PL_DHASH_REMOVE);
// N.B. that we _don't_ release the literal: we only held a weak
// reference to it in the hashtable.
PR_LOG(gLog, PR_LOG_DEBUG,
("rdfserv unregister-int [%p] %d",
aInt, value));
return NS_OK;
}
//----------------------------------------------------------------------
nsresult
RDFServiceImpl::RegisterDate(nsIRDFDate* aDate)
{
PRTime value;
aDate->GetValue(&value);
NS_ASSERTION(PL_DHASH_ENTRY_IS_FREE(PL_DHashTableOperate(&mDates,
&value,
PL_DHASH_LOOKUP)),
"date already registered");
PLDHashEntryHdr *hdr =
PL_DHashTableOperate(&mDates, &value, PL_DHASH_ADD);
if (! hdr)
return NS_ERROR_OUT_OF_MEMORY;
DateHashEntry *entry = NS_STATIC_CAST(DateHashEntry *, hdr);
// N.B., we only hold a weak reference to the literal: that
// way, the literal can be destroyed when the last refcount
// goes away. The single addref that the CreateDate() call
// made will be owned by the callee.
entry->mDate = aDate;
entry->mKey = value;
PR_LOG(gLog, PR_LOG_DEBUG,
("rdfserv register-date [%p] %ld",
aDate, value));
return NS_OK;
}
nsresult
RDFServiceImpl::UnregisterDate(nsIRDFDate* aDate)
{
PRTime value;
aDate->GetValue(&value);
NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(PL_DHashTableOperate(&mDates,
&value,
PL_DHASH_LOOKUP)),
"date was never registered");
PL_DHashTableOperate(&mDates, &value, PL_DHASH_REMOVE);
// N.B. that we _don't_ release the literal: we only held a weak
// reference to it in the hashtable.
PR_LOG(gLog, PR_LOG_DEBUG,
("rdfserv unregister-date [%p] %ld",
aDate, value));
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
nsresult