source: GTP/trunk/Lib/Vis/Preprocessing/src/HashPvs.h @ 2162

Revision 2162, 7.6 KB checked in by mattausch, 17 years ago (diff)

improved hash performance with google hashmap

Line 
1#ifndef __HASHPVS_H
2#define __HASHPVS_H
3
4
5#include <hash_set>
6#include "common.h"
7#include <math.h>
8#include "PvsBase.h"
9#include "google/dense_hash_set"
10#include "google/dense_hash_map"
11
12
13using namespace std;
14
15namespace GtpVisibilityPreprocessor {
16
17
18template<typename T>
19struct my_hash_compare
20{
21   enum
22   {
23      bucket_size = 1,
24      min_buckets = 16
25   };
26
27   /*int operator()(T a) const
28   {
29           if (!a)
30                   return -2;
31           return (size_t)(a->GetId());
32   }*/
33
34   int operator()(int a) const
35   {
36           return a;
37   }
38
39
40   bool operator()(T a, T b) const
41   {
42      return a < b;
43   }
44};
45
46
47//#define HASH_SET google::dense_hash_set<T, my_hash_compare<T> >
48#define HASH_SET google::dense_hash_map<int, T>//, hash_compare<int> >
49//#define HASH_SET stdext::hash_set<T, my_hash_compare<T> >
50#define HASH_ITERATOR HASH_SET::iterator
51#define CONST_HASH_ITERATOR HASH_SET::const_iterator
52
53/** Iterator over a hash pvs.
54*/
55template<typename T, typename S>
56class HashPvsIterator
57{
58public:
59       
60        HashPvsIterator<T, S>() {}
61
62        HashPvsIterator<T, S>(const typename CONST_HASH_ITERATOR &itCurrent,
63                                                  const typename CONST_HASH_ITERATOR &itEnd):
64        mItCurrent(itCurrent), mItEnd(itEnd)
65        {
66        }
67
68        bool HasMoreEntries() const
69        {
70                return (mItCurrent != mItEnd);
71        }
72
73        T Next(S &pdf)
74        {
75                T sample = (*mItCurrent).second;
76                ++ mItCurrent;
77
78                return sample;
79        }
80
81        T Next()
82        {
83                T sample = (*mItCurrent).second;
84                ++ mItCurrent;
85
86                return sample;
87        }
88       
89private:
90        typename CONST_HASH_ITERATOR mItCurrent;
91        typename CONST_HASH_ITERATOR mItEnd;
92};
93
94
95/** Template class representing the Potentially Visible Set (PVS)
96        mainly from a view cell, but also e.g., from objects.
97*/
98template<typename T, typename S>
99class HashPvs//: public PvsBase<T>
100{
101        template<typename T, typename S> friend class HashPvsIterator;
102
103public:
104
105        //HashPvs(): mEntries((Intersectable *)100) {};
106        HashPvs()
107        {
108                 mEntries.set_deleted_key(-1);
109                 mEntries.set_empty_key(-2);
110                 //mEntries.Reset();
111        };
112        //virtual ~HashPvs() {};
113
114        int GetSize() const;
115        bool Empty() const;
116
117        /** Adds sample to PVS.
118                @returns contribution of sample (0 or 1)
119        */
120        float AddSample(T sample, const float pdf);
121
122        /** Adds sample to PVS without checking for presence of the sample
123                warning: pvs remains unsorted!
124        */
125        void AddSampleDirty(T sample, const float pdf);
126
127        /** Adds sample dirty (on the end of the vector) but
128                first checks if sample is already in clean part of the pvs.
129        */
130        bool AddSampleDirtyCheck(T sample, const float pdf);
131
132        /** Sort pvs entries - this should always be called after a
133                sequence of AddSampleDirty calls
134        */
135        void Sort();
136
137        /** Clears the pvs.
138        */
139        void Clear(const bool trim = true);
140
141        bool IsDirty() const;
142
143        bool RequiresResort() const;
144
145        /** Finds sample in PVS.
146                @param checkDirty if dirty part of the pvs should be checked for entry
147                (warning: linear runtime in dirty part)
148                @returns iterator on the sample if found, else the place where
149                it would be added in the sorted vector.
150        */
151        inline bool Find(T sample, typename HASH_ITERATOR &it);
152
153        typename HashPvsIterator<T, S> GetIterator() const;
154
155        /** Compute continuous PVS difference
156        */
157        float GetPvsHomogenity(HashPvs<T, S> &pvs);
158
159        static void Merge(HashPvs<T, S> &mergedPvs,
160                                          const HashPvs<T, S> &a,
161                                          const HashPvs<T, S> &b);
162
163        static int GetEntrySizeByte();
164        static float GetEntrySize();
165
166        bool GetSampleContribution(T sample,
167                                                   const float pdf,
168                                                           float &contribution);
169
170        int GetSamples() const
171        {
172                return mSamples;
173        }
174
175        void MergeInPlace(const HashPvs<T, S> &a)
176        {
177                cerr << "not implemented yet" << endl;
178        }
179
180        bool RequiresResortLog() const
181        {
182                return false;
183        }
184
185        void Reserve(const int n)
186        {
187                // not necessary
188        }
189
190        /** Sort pvs entries assume that the pvs contains unique entries
191        */
192        void SimpleSort()
193        {
194                // not necessary
195        }
196
197        int SubtractPvs(const HashPvs<T, S> &pvs)
198        {
199                cerr << "not yet implemented" << endl;
200                return 0;
201        }
202
203        /** Compute continuous PVS difference
204        */
205        void ComputeContinuousPvsDifference(HashPvs<T, S> &pvs,
206                                                                                float &pvsReduction,
207                                                                                float &pvsEnlargement)
208        {
209                cerr << "not yet implemented" << endl;
210        }
211protected:
212
213        /// hash table of PVS entries
214        HASH_SET mEntries;
215
216        /// Number of samples used to create the PVS
217        int mSamples;
218};
219
220
221template <typename T, typename S>
222bool HashPvs<T, S>::Find(T sample, typename HASH_ITERATOR &it)
223{
224        it = mEntries.find(sample->GetId());
225
226        // already in map
227        return (it != mEntries.end());
228}
229
230
231template <typename T, typename S>
232int HashPvs<T, S>::GetSize() const
233{
234        return (int)mEntries.size();
235}
236
237
238template <typename T, typename S>
239bool HashPvs<T, S>::Empty() const
240{
241        return mEntries.empty();
242}
243
244
245template <typename T, typename S>
246float HashPvs<T, S>::AddSample(T sample, const float pdf)
247{
248        static HASH_ITERATOR it;
249
250        if (Find(sample, it))
251                return 0.0f;
252       
253        mEntries.insert(pair<int, T>(sample->GetId(), sample));
254        return 1.0f;
255}
256       
257
258template <typename T, typename S>
259void HashPvs<T, S>::AddSampleDirty(T sample, const float pdf)
260{
261        static HASH_ITERATOR it;
262
263        // not yet in map
264        if (!Find(sample, it))
265        {
266                mEntries.insert(pair<int, T>(sample->GetId(), sample));
267        }
268}
269
270
271template <typename T, typename S>
272bool HashPvs<T, S>::AddSampleDirtyCheck(T sample,
273                                                                                const float pdf)
274{
275        static CONST_HASH_ITERATOR it;
276
277        it = mEntries.find(sample->GetId());//, sample);
278
279        // already in map
280        const bool found = (it != mEntries.end());
281
282        // already in map
283        if (found)
284        //if (Find(pair<int, T>(sample->GetId(), sample), it))
285                return false;
286
287        mEntries.insert(pair<int, T>(sample->GetId(), sample));
288       
289        return true;
290}
291
292
293template <typename T, typename S>
294void HashPvs<T, S>::Sort()
295{
296}
297
298
299template <typename T, typename S>
300void HashPvs<T, S>::Clear(const bool trim = true)
301{
302        mEntries.clear();
303}
304
305
306template <typename T, typename S>
307bool HashPvs<T, S>::IsDirty() const
308{
309        return false;
310}
311
312
313template <typename T, typename S>
314bool HashPvs<T, S>::RequiresResort() const
315{
316        return false;
317}
318
319
320template <typename T, typename S>
321typename HashPvsIterator<T, S> HashPvs<T, S>::GetIterator() const
322{
323        HashPvsIterator<T, S> pit(mEntries.begin(), mEntries.end());
324
325        return pit;
326}
327
328
329template <typename T, typename S>
330float HashPvs<T, S>::GetEntrySize()
331{
332        return (float)(sizeof(T)) / float(1024 * 1024);
333}
334
335
336template <typename T, typename S>
337int HashPvs<T, S>::GetEntrySizeByte()
338{
339        return sizeof(T);
340}
341
342
343template <typename T, typename S>
344float HashPvs<T, S>::GetPvsHomogenity(HashPvs<T, S> &pvs)
345{
346        float pvsReduction, pvsEnlargement;
347
348        ComputeContinuousPvsDifference(pvs,     pvsReduction, pvsEnlargement);
349
350        return pvsReduction + pvsEnlargement;
351}
352
353
354template <typename T, typename S>
355bool HashPvs<T, S>::GetSampleContribution(T sample,
356                                                                          const float pdf,
357                                                                          float &contribution)
358{
359        HASH_SET::iterator it;
360        const bool entryFound = Find(sample, it);
361
362        if (entryFound) 
363        {
364                contribution = 0.0f;
365                return false;
366        }
367        else
368        {
369                contribution = 1.0f;
370                return true;
371        }
372}
373
374
375template <typename T, typename S>
376void HashPvs<T, S>::Merge(HashPvs<T, S> &mergedPvs,
377                                                  const HashPvs<T, S> &a,
378                                                  const HashPvs<T, S> &b)
379{
380        CONST_HASH_ITERATOR ait, ait_end = a.mEntries.end();
381
382        for (ait = a.mEntries.begin(); ait != ait_end; ++ ait)
383        {
384                mergedPvs.AddSample((*ait).second, 1.0f);
385        }
386
387        CONST_HASH_ITERATOR bit, bit_end = b.mEntries.end();
388
389        for (bit = b.mEntries.begin(); bit != bit_end; ++ bit)
390        {
391                mergedPvs.AddSample((*bit).second, 1.0f);
392        }
393}
394
395}
396
397#endif
398
Note: See TracBrowser for help on using the repository browser.