Index: src/pdf/SkTSet.h |
diff --git a/src/pdf/SkTSet.h b/src/pdf/SkTSet.h |
deleted file mode 100644 |
index f57d30eccb858b543479717b6a45444c11548885..0000000000000000000000000000000000000000 |
--- 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 |