diff options
Diffstat (limited to 'src/pdf/SkTSet.h')
-rw-r--r-- | src/pdf/SkTSet.h | 356 |
1 files changed, 0 insertions, 356 deletions
diff --git a/src/pdf/SkTSet.h b/src/pdf/SkTSet.h deleted file mode 100644 index f57d30eccb..0000000000 --- a/src/pdf/SkTSet.h +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkTSet_DEFINED -#define SkTSet_DEFINED - -#include "SkTSort.h" -#include "SkTDArray.h" -#include "SkTypes.h" - -/** \class SkTSet<T> - - The SkTSet template class defines a set. Elements are additionally - guaranteed to be sorted by their insertion order. - Main operations supported now are: add, merge, find and contains. - - TSet<T> is mutable. -*/ - -// TODO: Add remove, intersect and difference operations. -// TODO: Add bench tests. -template <typename T> class SkTSet { -public: - SkTSet() { - fSetArray = SkNEW(SkTDArray<T>); - fOrderedArray = SkNEW(SkTDArray<T>); - } - - ~SkTSet() { - SkASSERT(fSetArray); - SkDELETE(fSetArray); - SkASSERT(fOrderedArray); - SkDELETE(fOrderedArray); - } - - SkTSet(const SkTSet<T>& src) { - this->fSetArray = SkNEW_ARGS(SkTDArray<T>, (*src.fSetArray)); - this->fOrderedArray = SkNEW_ARGS(SkTDArray<T>, (*src.fOrderedArray)); -#ifdef SK_DEBUG - validate(); -#endif - } - - SkTSet<T>& operator=(const SkTSet<T>& src) { - *this->fSetArray = *src.fSetArray; - *this->fOrderedArray = *src.fOrderedArray; -#ifdef SK_DEBUG - validate(); -#endif - return *this; - } - - /** Merges src elements into this, and returns the number of duplicates - * found. Elements from src will retain their ordering and will be ordered - * after the elements currently in this set. - * - * Implementation note: this uses a 2-stage merge to obtain O(n log n) time. - * The first stage goes through src.fOrderedArray, checking if - * this->contains() is false before adding to this.fOrderedArray. - * The second stage does a standard sorted list merge on the fSetArrays. - */ - int mergeInto(const SkTSet<T>& src) { - SkASSERT(fSetArray); - SkASSERT(fOrderedArray); - - // Do fOrderedArray merge. - for (int i = 0; i < src.count(); ++i) { - if (!contains((*src.fOrderedArray)[i])) { - fOrderedArray->push((*src.fOrderedArray)[i]); - } - } - - // Do fSetArray merge. - int duplicates = 0; - - SkTDArray<T>* fArrayNew = new SkTDArray<T>(); - fArrayNew->setReserve(fOrderedArray->count()); - int i = 0; - int j = 0; - - while (i < fSetArray->count() && j < src.count()) { - if ((*fSetArray)[i] < (*src.fSetArray)[j]) { - fArrayNew->push((*fSetArray)[i]); - i++; - } else if ((*fSetArray)[i] > (*src.fSetArray)[j]) { - fArrayNew->push((*src.fSetArray)[j]); - j++; - } else { - duplicates++; - j++; // Skip one of the duplicates. - } - } - - while (i < fSetArray->count()) { - fArrayNew->push((*fSetArray)[i]); - i++; - } - - while (j < src.count()) { - fArrayNew->push((*src.fSetArray)[j]); - j++; - } - SkDELETE(fSetArray); - fSetArray = fArrayNew; - fArrayNew = NULL; - -#ifdef SK_DEBUG - validate(); -#endif - return duplicates; - } - - /** Adds a new element into set and returns false if the element is already - * in this set. - */ - bool add(const T& elem) { - SkASSERT(fSetArray); - SkASSERT(fOrderedArray); - - int pos = 0; - int i = find(elem, &pos); - if (i >= 0) { - return false; - } - *fSetArray->insert(pos) = elem; - fOrderedArray->push(elem); -#ifdef SK_DEBUG - validate(); -#endif - return true; - } - - /** Returns true if this set is empty. - */ - bool isEmpty() const { - SkASSERT(fOrderedArray); - SkASSERT(fSetArray); - SkASSERT(fSetArray->isEmpty() == fOrderedArray->isEmpty()); - return fOrderedArray->isEmpty(); - } - - /** Return the number of elements in the set. - */ - int count() const { - SkASSERT(fOrderedArray); - SkASSERT(fSetArray); - SkASSERT(fSetArray->count() == fOrderedArray->count()); - return fOrderedArray->count(); - } - - /** Return the number of bytes in the set: count * sizeof(T). - */ - size_t bytes() const { - SkASSERT(fOrderedArray); - return fOrderedArray->bytes(); - } - - /** Return the beginning of a set iterator. - * Elements in the iterator will be sorted ascending. - */ - const T* begin() const { - SkASSERT(fOrderedArray); - return fOrderedArray->begin(); - } - - /** Return the end of a set iterator. - */ - const T* end() const { - SkASSERT(fOrderedArray); - return fOrderedArray->end(); - } - - const T& operator[](int index) const { - SkASSERT(fOrderedArray); - return (*fOrderedArray)[index]; - } - - /** Resets the set (deletes memory and initiates an empty set). - */ - void reset() { - SkASSERT(fSetArray); - SkASSERT(fOrderedArray); - fSetArray->reset(); - fOrderedArray->reset(); - } - - /** Rewinds the set (preserves memory and initiates an empty set). - */ - void rewind() { - SkASSERT(fSetArray); - SkASSERT(fOrderedArray); - fSetArray->rewind(); - fOrderedArray->rewind(); - } - - /** Reserves memory for the set. - */ - void setReserve(int reserve) { - SkASSERT(fSetArray); - SkASSERT(fOrderedArray); - fSetArray->setReserve(reserve); - fOrderedArray->setReserve(reserve); - } - - /** Returns true if the array contains this element. - */ - bool contains(const T& elem) const { - SkASSERT(fSetArray); - return (this->find(elem) >= 0); - } - - /** Copies internal array to destination. - */ - void copy(T* dst) const { - SkASSERT(fOrderedArray); - fOrderedArray->copyRange(dst, 0, fOrderedArray->count()); - } - - /** Returns a const reference to the internal vector. - */ - const SkTDArray<T>& toArray() { - SkASSERT(fOrderedArray); - return *fOrderedArray; - } - - /** Unref all elements in the set. - */ - void unrefAll() { - SkASSERT(fSetArray); - SkASSERT(fOrderedArray); - fOrderedArray->unrefAll(); - // Also reset the other array, as SkTDArray::unrefAll does an - // implcit reset - fSetArray->reset(); - } - - /** safeUnref all elements in the set. - */ - void safeUnrefAll() { - SkASSERT(fSetArray); - SkASSERT(fOrderedArray); - fOrderedArray->safeUnrefAll(); - // Also reset the other array, as SkTDArray::safeUnrefAll does an - // implcit reset - fSetArray->reset(); - } - -#ifdef SK_DEBUG - void validate() const { - SkASSERT(fSetArray); - SkASSERT(fOrderedArray); - fSetArray->validate(); - fOrderedArray->validate(); - SkASSERT(isSorted() && !hasDuplicates() && arraysConsistent()); - } - - bool hasDuplicates() const { - for (int i = 0; i < fSetArray->count() - 1; ++i) { - if ((*fSetArray)[i] == (*fSetArray)[i + 1]) { - return true; - } - } - return false; - } - - bool isSorted() const { - for (int i = 0; i < fSetArray->count() - 1; ++i) { - // Use only < operator - if (!((*fSetArray)[i] < (*fSetArray)[i + 1])) { - return false; - } - } - return true; - } - - /** Checks if fSetArray is consistent with fOrderedArray - */ - bool arraysConsistent() const { - if (fSetArray->count() != fOrderedArray->count()) { - return false; - } - if (fOrderedArray->count() == 0) { - return true; - } - - // Copy and sort fOrderedArray, then compare to fSetArray. - // A O(n log n) algorithm is necessary as O(n^2) will choke some GMs. - SkAutoMalloc sortedArray(fOrderedArray->bytes()); - T* sortedBase = reinterpret_cast<T*>(sortedArray.get()); - int count = fOrderedArray->count(); - fOrderedArray->copyRange(sortedBase, 0, count); - - SkTQSort<T>(sortedBase, sortedBase + count - 1); - - for (int i = 0; i < count; ++i) { - if (sortedBase[i] != (*fSetArray)[i]) { - return false; - } - } - - return true; - } -#endif - -private: - SkTDArray<T>* fSetArray; // Sorted by pointer address for fast - // lookup. - SkTDArray<T>* fOrderedArray; // Sorted by insertion order for - // deterministic output. - - /** Returns the index in fSetArray where an element was found. - * Returns -1 if the element was not found, and it fills *posToInsertSorted - * with the index of the place where elem should be inserted to preserve the - * internal array sorted. - * If element was found, *posToInsertSorted is undefined. - */ - int find(const T& elem, int* posToInsertSorted = NULL) const { - SkASSERT(fSetArray); - - if (fSetArray->count() == 0) { - if (posToInsertSorted) { - *posToInsertSorted = 0; - } - return -1; - } - int iMin = 0; - int iMax = fSetArray->count(); - - while (iMin < iMax - 1) { - int iMid = (iMin + iMax) / 2; - if (elem < (*fSetArray)[iMid]) { - iMax = iMid; - } else { - iMin = iMid; - } - } - if (elem == (*fSetArray)[iMin]) { - return iMin; - } - if (posToInsertSorted) { - if (elem < (*fSetArray)[iMin]) { - *posToInsertSorted = iMin; - } else { - *posToInsertSorted = iMin + 1; - } - } - - return -1; - } -}; - -#endif |