duke@435: /* trims@1907: * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: duke@435: #ifndef _VECTOR_SET_ duke@435: #define _VECTOR_SET_ duke@435: // Vector Sets - An Abstract Data Type duke@435: //INTERFACE duke@435: duke@435: // These sets can grow or shrink, based on the initial size and the largest duke@435: // element currently in them. Slow and bulky for sparse sets, these sets duke@435: // are super for dense sets. They are fast and compact when dense. duke@435: duke@435: // TIME: duke@435: // O(1) - Insert, Delete, Member, Sort duke@435: // O(max_element) - Create, Clear, Size, Copy, Union, Intersect, Difference, duke@435: // Equal, ChooseMember, Forall duke@435: duke@435: // SPACE: (max_element)/(8*sizeof(int)) duke@435: duke@435: duke@435: //------------------------------VectorSet-------------------------------------- duke@435: class VectorSet : public Set { duke@435: friend class VectorSetI; // Friendly iterator class duke@435: protected: duke@435: uint size; // Size of data IN LONGWORDS (32bits) duke@435: uint32 *data; // The data, bit packed duke@435: duke@435: void slamin( const VectorSet& s ); // Initialize one set with another duke@435: int compare(const VectorSet &s) const; // Compare set contents duke@435: void grow(uint newsize); // Grow vector to required bitsize duke@435: duke@435: public: duke@435: VectorSet(Arena *arena); // Creates a new, empty set. duke@435: VectorSet(const VectorSet &s) : Set(s._set_arena) {slamin(s);} // Set clone; deep-copy guts duke@435: Set &operator =(const Set &s); // Set clone; deep-copy guts duke@435: VectorSet &operator =(const VectorSet &s) // Set clone; deep-copy guts duke@435: { if( &s != this ) { slamin(s); } return *this; } duke@435: ~VectorSet() {} duke@435: Set &clone(void) const { return *(new VectorSet(*this)); } duke@435: duke@435: Set &operator <<=(uint elem); // Add member to set duke@435: VectorSet operator << (uint elem) // Add member to new set duke@435: { VectorSet foo(*this); foo <<= elem; return foo; } duke@435: Set &operator >>=(uint elem); // Delete member from set duke@435: VectorSet operator >> (uint elem) // Delete member from new set duke@435: { VectorSet foo(*this); foo >>= elem; return foo; } duke@435: duke@435: VectorSet &operator &=(const VectorSet &s); // Intersect sets into first set duke@435: Set &operator &=(const Set &s); // Intersect sets into first set duke@435: VectorSet operator & (const VectorSet &s) const duke@435: { VectorSet foo(*this); foo &= s; return foo; } duke@435: duke@435: VectorSet &operator |=(const VectorSet &s); // Intersect sets into first set duke@435: Set &operator |=(const Set &s); // Intersect sets into first set duke@435: VectorSet operator | (const VectorSet &s) const duke@435: { VectorSet foo(*this); foo |= s; return foo; } duke@435: duke@435: VectorSet &operator -=(const VectorSet &s); // Intersect sets into first set duke@435: Set &operator -=(const Set &s); // Intersect sets into first set duke@435: VectorSet operator - (const VectorSet &s) const duke@435: { VectorSet foo(*this); foo -= s; return foo; } duke@435: duke@435: int operator ==(const VectorSet &s) const; // True if sets are equal duke@435: int operator ==(const Set &s) const; // True if sets are equal duke@435: int operator < (const VectorSet &s) const; // True if strict subset duke@435: int operator < (const Set &s) const; // True if strict subset duke@435: int operator <=(const VectorSet &s) const; // True if subset relation holds. duke@435: int operator <=(const Set &s) const; // True if subset relation holds. duke@435: int disjoint (const Set &s) const; // True if sets are disjoint duke@435: duke@435: int operator [](uint elem) const; // Test for membership duke@435: uint getelem(void) const; // Return a random element duke@435: void Clear(void); // Clear a set duke@435: uint Size(void) const; // Number of elements in the Set. duke@435: void Sort(void); // Sort before iterating duke@435: int hash() const; // Hash function duke@435: duke@435: /* Removed for MCC BUG duke@435: operator const VectorSet* (void) const { return this; } */ duke@435: const VectorSet *asVectorSet() const { return this; } duke@435: duke@435: // Expose internals for speed-critical fast iterators duke@435: uint word_size() const { return size; } duke@435: uint32 *EXPOSE() const { return data; } duke@435: duke@435: // Fast inlined "test and set". Replaces the idiom: duke@435: // if( visited[idx] ) return; duke@435: // visited <<= idx; duke@435: // With: duke@435: // if( visited.test_set(idx) ) return; duke@435: // duke@435: int test_set( uint elem ) { duke@435: uint word = elem >> 5; // Get the longword offset duke@435: if( word >= size ) // Beyond the last? duke@435: return test_set_grow(elem); // Then grow; set; return 0; duke@435: uint32 mask = 1L << (elem & 31); // Get bit mask duke@435: uint32 datum = data[word] & mask;// Get bit duke@435: data[word] |= mask; // Set bit duke@435: return datum; // Return bit duke@435: } duke@435: int test_set_grow( uint elem ) { // Insert & return 0; duke@435: (*this) <<= elem; // Insert into set duke@435: return 0; // Return 0! duke@435: } duke@435: duke@435: // Fast inlined test duke@435: int test( uint elem ) const { duke@435: uint word = elem >> 5; // Get the longword offset duke@435: if( word >= size ) return 0; // Beyond the last? duke@435: uint32 mask = 1L << (elem & 31); // Get bit mask duke@435: return data[word] & mask; // Get bit duke@435: } duke@435: duke@435: // Fast inlined set duke@435: void set( uint elem ) { duke@435: uint word = elem >> 5; // Get the longword offset duke@435: if( word >= size ) { // Beyond the last? duke@435: test_set_grow(elem); // Then grow and set duke@435: } else { duke@435: uint32 mask = 1L << (elem & 31); // Get bit mask duke@435: data[word] |= mask; // Set bit duke@435: } duke@435: } duke@435: duke@435: duke@435: private: duke@435: friend class VSetI_; duke@435: SetI_ *iterate(uint&) const; duke@435: }; duke@435: duke@435: //------------------------------Iteration-------------------------------------- duke@435: // Loop thru all elements of the set, setting "elem" to the element numbers duke@435: // in random order. Inserted or deleted elements during this operation may duke@435: // or may not be iterated over; untouched elements will be affected once. duke@435: // Usage: for( VectorSetI i(s); i.test(); i++ ) { body = i.elem; } duke@435: duke@435: class VSetI_ : public SetI_ { duke@435: friend class VectorSet; duke@435: friend class VectorSetI; duke@435: const VectorSet *s; duke@435: uint i, j; duke@435: uint32 mask; duke@435: VSetI_(const VectorSet *vset); duke@435: uint next(void); duke@435: int test(void) { return i < s->size; } duke@435: }; duke@435: duke@435: class VectorSetI : public SetI { duke@435: public: duke@435: VectorSetI( const VectorSet *s ) : SetI(s) { } duke@435: void operator ++(void) { elem = ((VSetI_*)impl)->next(); } duke@435: int test(void) { return ((VSetI_*)impl)->test(); } duke@435: }; duke@435: duke@435: #endif // _VECTOR_SET_