/* * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Set.cc * * Description: See Set.hh * * $Id: BigSet.cc 1.9 05/01/19 13:12:25-06:00 mikem@maya.cs.wisc.edu $ * */ // modified (rewritten) 05/20/05 by Dan Gibson to accomimdate FASTER >32 bit // set sizes #include "mem/ruby/common/Set.hh" #include "mem/ruby/system/System.hh" #if __amd64__ || __LP64__ #define __64BITS__ #else #define __32BITS__ #endif Set::Set() { m_p_nArray = NULL; m_nArrayLen = 0; m_nSize = 0; } // copy constructor Set::Set(const Set& obj) { m_p_nArray = NULL; setSize(obj.m_nSize); // copy from the host to this array for(int i=0; i 0) { setSize(size); } } Set::~Set() { if( (m_p_nArray != (&m_p_nArray_Static[0])) && (m_p_nArray != NULL)) delete [] m_p_nArray; m_p_nArray = NULL; } // /* // * This function should set the bit corresponding to index // * to 1. // */ // void Set::add(NodeID index) // { // assert(index= 0); // #ifdef __32BITS__ // m_p_nArray[index>>5] |= (1 << (index & 0x01F)); // #else // m_p_nArray[index>>6] |= (((unsigned long) 1) << (index & 0x03F)); // #endif // __32BITS__ // } /* * This function should set all the bits in the current set * that are already set in the parameter set */ void Set::addSet(const Set& set) { assert(getSize()==set.getSize()); for(int i=0; i> 1; } } #else long mask = 0x7FFFFFFFFFFFFFFF; // the number of populated spaces in the higest-order array slot is: // m_nSize % 64, so the uppermost 64 - m_nSize%64 bits should be // cleared if((m_nSize % 64) != 0) { for(int j=0; j<64-(m_nSize&0x03F); j++) { m_p_nArray[m_nArrayLen-1] &= mask; mask = mask >> 1; } } #endif // __32BITS__ } // /* // * This function unsets the bit associated with index // */ // void Set::remove(NodeID index) // { // assert(index=0); // #ifdef __32BITS__ // m_p_nArray[index>>5] &= ~(0x00000001 << (index & 0x01F)); // #else // m_p_nArray[index>>6] &= ~(((unsigned long) 0x0000000000000001) << (index & 0x03F)); // #endif // __32BITS__ // } /* * This function clears bits that are =1 in the parameter set */ void Set::removeSet(const Set& set) { assert(m_nSize==set.m_nSize); for(int i=0; i> 1; } } #else long mask = 0x7FFFFFFFFFFFFFFF; // the number of populated spaces in the higest-order array slot is: // m_nSize % 64, so the uppermost 64 - m_nSize%64 bits should be // cleared if((m_nSize % 64) != 0) { for(int j=0; j<64-(m_nSize&0x03F); j++) { m_p_nArray[m_nArrayLen-1] &= mask; mask = mask >> 1; } } #endif // __32BITS__ } /* * This function returns the population count of 1's in the set */ int Set::count() const { int counter = 0; long mask; for( int i=0; i 0); long x; for( int i=0; i> 1; } #else for( int j=0; j<64; j++) { if(x & 0x0000000000000001) { return 64*i+j; } x = x >> 1; } #endif // __32BITS__ ERROR_MSG("No smallest element of an empty set."); } } ERROR_MSG("No smallest element of an empty set."); return 0; } /* * this function returns true iff all bits are set */ bool Set::isBroadcast() const { // check the fully-loaded words by equal to 0xffffffff // only the last word may not be fully loaded, it is not // fully loaded iff m_nSize % 32 or 64 !=0 => fully loaded iff // m_nSize % 32 or 64 == 0 #ifdef __32BITS__ for(int i=0; i< (((m_nSize % 32)==0) ? m_nArrayLen : m_nArrayLen-1); i++) { if(m_p_nArray[i]!=-1) { return false; } } // now check the last word, which may not be fully loaded long mask = 1; for(int j=0; j< (m_nSize % 32); j++) { if((mask & m_p_nArray[m_nArrayLen-1])==0) { return false; } mask = mask << 1; } #else for(int i=0; i< (((m_nSize % 64)==0) ? m_nArrayLen : m_nArrayLen-1); i++) { if(m_p_nArray[i]!=-1) { return false; } } // now check the last word, which may not be fully loaded long mask = 1; for(int j=0; j< (m_nSize % 64); j++) { if((mask & m_p_nArray[m_nArrayLen-1])==0) { return false; } mask = mask << 1; } #endif // __32BITS__ return true; } /* * this function returns true iff no bits are set */ bool Set::isEmpty() const { // here we can simply check if all = 0, since we ensure // that "extra slots" are all zero for(int i=0; i< m_nArrayLen ; i++) { if(m_p_nArray[i]!=0) { return false; } } return true; } // returns the logical OR of "this" set and orSet Set Set::OR(const Set& orSet) const { Set result(m_nSize); assert(m_nSize == orSet.m_nSize); for(int i=0; i< m_nArrayLen; i++) { result.m_p_nArray[i] = m_p_nArray[i] | orSet.m_p_nArray[i]; } return result; } // returns the logical AND of "this" set and andSet Set Set::AND(const Set& andSet) const { Set result(m_nSize); assert(m_nSize == andSet.m_nSize); for(int i=0; i< m_nArrayLen; i++) { result.m_p_nArray[i] = m_p_nArray[i] & andSet.m_p_nArray[i]; } return result; } // // Returns true if the intersection of the two sets is non-empty // bool Set::intersectionIsNotEmpty(const Set& other_set) const // { // assert(m_nSize == other_set.m_nSize); // for(int i=0; i< m_nArrayLen; i++) { // if(m_p_nArray[i] & other_set.m_p_nArray[i]) { // return true; // } // } // return false; // } // // Returns true if the intersection of the two sets is empty // bool Set::intersectionIsEmpty(const Set& other_set) const // { // assert(m_nSize == other_set.m_nSize); // for(int i=0; i< m_nArrayLen; i++) { // if(m_p_nArray[i] & other_set.m_p_nArray[i]) { // return false; // } // } // return true; // } /* * Returns false if a bit is set in the parameter set that is * NOT set in this set */ bool Set::isSuperset(const Set& test) const { assert(m_nSize == test.m_nSize); for(int i=0;i>5] & (0x00000001 << (element & 0x01F)))!=0); // #else // result = ((m_p_nArray[element>>6] & (((unsigned long) 0x0000000000000001) << (element & 0x03F)))!=0); // #endif // __32BITS__ // return result; // } /* * "Supposed" to return the node id of the (n+1)th set * bit, IE n=0 => returns nodeid of first set bit, BUT * since BigSet.cc behaves strangely, this implementation * will behave strangely just for reverse compatability. * * Was originally implemented for the flight data recorder * FDR */ // NodeID Set::elementAt(int n) const // { // if(isElement(n)) return (NodeID) true; // else return 0; // /* // int match = -1; // for(int i=0;i=0; i--) { #ifdef __32BITS__ sprintf(buff,"%08X ",m_p_nArray[i]); #else sprintf(buff,"0x %016llX ", (long long)m_p_nArray[i]); #endif // __32BITS__ out << buff; } out << " ]"; }