Back to index

lightning-sunbird  0.9+nobinonly
nsConflictSet.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Chris Waterson <waterson@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #ifndef nsConflictSet_h__
00040 #define nsConflictSet_h__
00041 
00042 #include "nscore.h"
00043 #include "plhash.h"
00044 #include "nsTemplateMatch.h"
00045 #include "nsTemplateMatchSet.h"
00046 #include "nsClusterKey.h"
00047 #include "nsIRDFResource.h"
00048 
00111 class nsConflictSet
00112 {
00113 public:
00118     class MatchCluster {
00119     public:
00120         MatchCluster() : mLastMatch(nsnull) {}
00121 
00122         nsTemplateMatchRefSet mMatches;
00123         nsTemplateMatch*      mLastMatch;
00124     };
00125 
00126     nsConflictSet()
00127         : mClusters(nsnull),
00128           mSupport(nsnull),
00129           mBindingDependencies(nsnull) {
00130         MOZ_COUNT_CTOR(nsConflictSet);
00131         Init(); }
00132 
00133     ~nsConflictSet() {
00134         MOZ_COUNT_DTOR(nsConflictSet);
00135         Destroy(); }
00136 
00142     nsresult
00143     Add(nsTemplateMatch* aMatch);
00144 
00154     MatchCluster*
00155     GetMatchesForClusterKey(const nsClusterKey& aKey);
00156 
00162     nsTemplateMatch*
00163     GetMatchWithHighestPriority(const MatchCluster* aMatchCluster) const;
00164 
00171     const nsTemplateMatchRefSet*
00172     GetMatchesWithBindingDependency(nsIRDFResource* aSource);
00173 
00184     void
00185     Remove(const MemoryElement& aMemoryElement,
00186            nsTemplateMatchSet& aNewMatches,
00187            nsTemplateMatchSet& aRetractedMatches);
00188 
00192     nsresult
00193     AddBindingDependency(nsTemplateMatch* aMatch, nsIRDFResource* aResource);
00194 
00198     nsresult
00199     RemoveBindingDependency(nsTemplateMatch* aMatch, nsIRDFResource* aResource);
00200 
00205     void Clear();
00206 
00211     nsFixedSizeAllocator& GetPool() { return mPool; }
00212 
00213 protected:
00214     nsresult Init();
00215     nsresult Destroy();
00216 
00217     nsresult
00218     ComputeNewMatches(nsTemplateMatchSet& aNewMatches, 
00219                       nsTemplateMatchSet& aRetractedMatches);
00220 
00227     PLHashTable* mClusters;
00228 
00229     class ClusterEntry {
00230     private:
00231         // Hide so that only Create() and Destroy() can be used to
00232         // allocate and deallocate from the heap
00233         static void* operator new(size_t) CPP_THROW_NEW { return 0; }
00234         static void operator delete(void*, size_t) {}
00235 
00236     public:
00237         ClusterEntry() { MOZ_COUNT_CTOR(nsConflictSet::ClusterEntry); }
00238         ~ClusterEntry() { MOZ_COUNT_DTOR(nsConflictSet::ClusterEntry); }
00239 
00240         static ClusterEntry*
00241         Create(nsFixedSizeAllocator& aPool) {
00242             void* place = aPool.Alloc(sizeof(ClusterEntry));
00243             return place ? ::new (place) ClusterEntry() : nsnull; }
00244 
00245         static void
00246         Destroy(nsFixedSizeAllocator& aPool, ClusterEntry* aEntry) {
00247             aEntry->~ClusterEntry();
00248             aPool.Free(aEntry, sizeof(*aEntry)); }
00249 
00250         PLHashEntry  mHashEntry;
00251         nsClusterKey mKey;
00252         MatchCluster mCluster;
00253     };
00254 
00255     static PLHashAllocOps gClusterAllocOps;
00256 
00257     static void* PR_CALLBACK AllocClusterTable(void* aPool, PRSize aSize) {
00258         return new char[aSize]; }
00259 
00260     static void PR_CALLBACK FreeClusterTable(void* aPool, void* aItem) {
00261         delete[] NS_STATIC_CAST(char*, aItem); }
00262 
00263     static PLHashEntry* PR_CALLBACK AllocClusterEntry(void* aPool, const void* aKey) {
00264         nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
00265 
00266         ClusterEntry* entry = ClusterEntry::Create(*pool);
00267         if (! entry)
00268             return nsnull;
00269 
00270         entry->mKey = *NS_STATIC_CAST(const nsClusterKey*, aKey);
00271         return NS_REINTERPRET_CAST(PLHashEntry*, entry); }
00272 
00273     static void PR_CALLBACK FreeClusterEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) {
00274         nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
00275         if (aFlag == HT_FREE_ENTRY)
00276             ClusterEntry::Destroy(*pool, NS_REINTERPRET_CAST(ClusterEntry*, aHashEntry)); }
00277 
00284     PLHashTable* mSupport;
00285 
00286     class SupportEntry {
00287     private:
00288         // Hide so that only Create() and Destroy() can be used to
00289         // allocate and deallocate from the heap
00290         static void* operator new(size_t) CPP_THROW_NEW { return 0; }
00291         static void operator delete(void*, size_t) {}
00292 
00293     protected:
00294         SupportEntry() : mElement(nsnull)
00295             { MOZ_COUNT_CTOR(nsConflictSet::SupportEntry); }
00296 
00297         ~SupportEntry() {
00298             delete mElement;
00299             MOZ_COUNT_DTOR(nsConflictSet::SupportEntry); }
00300 
00301     public:
00302         static SupportEntry*
00303         Create(nsFixedSizeAllocator& aPool) {
00304             void* place = aPool.Alloc(sizeof(SupportEntry));
00305             return place ? ::new (place) SupportEntry() : nsnull; }
00306 
00307         static void
00308         Destroy(nsFixedSizeAllocator& aPool, SupportEntry* aEntry);
00309 
00310         PLHashEntry           mHashEntry;
00311         MemoryElement*        mElement;
00312         nsTemplateMatchRefSet mMatchSet;
00313     };
00314 
00315     static PLHashAllocOps gSupportAllocOps;
00316 
00317     static void* PR_CALLBACK AllocSupportTable(void* aPool, PRSize aSize) {
00318         return new char[aSize]; }
00319 
00320     static void PR_CALLBACK FreeSupportTable(void* aPool, void* aItem) {
00321         delete[] NS_STATIC_CAST(char*, aItem); }
00322 
00323     static PLHashEntry* PR_CALLBACK AllocSupportEntry(void* aPool, const void* aKey) {
00324         nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
00325 
00326         SupportEntry* entry = SupportEntry::Create(*pool);
00327         if (! entry)
00328             return nsnull;
00329 
00330         const MemoryElement* element = NS_STATIC_CAST(const MemoryElement*, aKey);
00331         entry->mElement = element->Clone(aPool);
00332 
00333         return NS_REINTERPRET_CAST(PLHashEntry*, entry); }
00334 
00335     static void PR_CALLBACK FreeSupportEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) {
00336         nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
00337         if (aFlag == HT_FREE_ENTRY)
00338             SupportEntry::Destroy(*pool, NS_REINTERPRET_CAST(SupportEntry*, aHashEntry)); }
00339 
00340     static PLHashNumber PR_CALLBACK HashMemoryElement(const void* aBinding);
00341     static PRIntn PR_CALLBACK CompareMemoryElements(const void* aLeft, const void* aRight);
00342 
00343 
00349     PLHashTable* mBindingDependencies;
00350 
00351     class BindingEntry {
00352     protected:
00353         // Hide so that only Create() and Destroy() can be used to
00354         // allocate and deallocate from the heap
00355         static void* operator new(size_t) CPP_THROW_NEW { return 0; }
00356         static void operator delete(void*, size_t) {}
00357 
00358     public:
00359         BindingEntry()
00360             { MOZ_COUNT_CTOR(nsConflictSet::BindingEntry); }
00361 
00362         ~BindingEntry()
00363             { MOZ_COUNT_DTOR(nsConflictSet::BindingEntry); }
00364 
00365         static BindingEntry*
00366         Create(nsFixedSizeAllocator& aPool) {
00367             void* place = aPool.Alloc(sizeof(BindingEntry));
00368             return place ? ::new (place) BindingEntry() : nsnull; }
00369 
00370         static void
00371         Destroy(nsFixedSizeAllocator& aPool, BindingEntry* aEntry) {
00372             aEntry->~BindingEntry();
00373             aPool.Free(aEntry, sizeof(*aEntry)); }
00374 
00375         PLHashEntry           mHashEntry;
00376         nsTemplateMatchRefSet mMatchSet;
00377     };
00378 
00379     static PLHashAllocOps gBindingAllocOps;
00380 
00381     static void* PR_CALLBACK AllocBindingTable(void* aPool, PRSize aSize) {
00382         return new char[aSize]; }
00383 
00384     static void PR_CALLBACK FreeBindingTable(void* aPool, void* aItem) {
00385         delete[] NS_STATIC_CAST(char*, aItem); }
00386 
00387     static PLHashEntry* PR_CALLBACK AllocBindingEntry(void* aPool, const void* aKey) {
00388         nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
00389 
00390         BindingEntry* entry = BindingEntry::Create(*pool);
00391         if (! entry)
00392             return nsnull;
00393 
00394         nsIRDFResource* key = NS_STATIC_CAST(nsIRDFResource*, NS_CONST_CAST(void*, aKey));
00395         NS_ADDREF(key);
00396 
00397         return NS_REINTERPRET_CAST(PLHashEntry*, entry); }
00398 
00399     static void PR_CALLBACK FreeBindingEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) {
00400         if (aFlag == HT_FREE_ENTRY) {
00401             nsIRDFResource* key = NS_STATIC_CAST(nsIRDFResource*, NS_CONST_CAST(void*, aHashEntry->key));
00402             NS_RELEASE(key);
00403             nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool);
00404             BindingEntry::Destroy(*pool, NS_REINTERPRET_CAST(BindingEntry*, aHashEntry));
00405         } }
00406 
00407     static PLHashNumber PR_CALLBACK HashBindingElement(const void* aSupport) {
00408         return PLHashNumber(NS_PTR_TO_INT32(aSupport)) >> 3; }
00409         
00410     static PRIntn PR_CALLBACK CompareBindingElements(const void* aLeft, const void* aRight) {
00411         return aLeft == aRight; }
00412 
00413     // The pool from whence all our slop will be allocated
00414     nsFixedSizeAllocator mPool;
00415 };
00416 
00417 #endif // nsConflictSet_h__