style: clean up ruby's Set class
Further cleanup should probably be done to make this class be non-Ruby specific and put it in src/base. There are probably several cases where this class is used, std::bitset could be used instead.
This commit is contained in:
parent
bb589d463b
commit
c1aabe8172
3 changed files with 304 additions and 567 deletions
|
@ -222,7 +222,7 @@ NetDest::intersectionIsNotEmpty(const NetDest& other_netDest) const
|
||||||
{
|
{
|
||||||
assert(m_bits.size() == other_netDest.getSize());
|
assert(m_bits.size() == other_netDest.getSize());
|
||||||
for (int i = 0; i < m_bits.size(); i++) {
|
for (int i = 0; i < m_bits.size(); i++) {
|
||||||
if (m_bits[i].intersectionIsNotEmpty(other_netDest.m_bits[i])) {
|
if (!m_bits[i].intersectionIsEmpty(other_netDest.m_bits[i])) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -27,27 +26,12 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
// modified (rewritten) 05/20/05 by Dan Gibson to accomimdate FASTER
|
||||||
* Set.cc
|
// >32 bit set sizes
|
||||||
*
|
|
||||||
* 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/common/Set.hh"
|
||||||
#include "mem/ruby/system/System.hh"
|
#include "mem/ruby/system/System.hh"
|
||||||
|
|
||||||
#if __amd64__ || __LP64__
|
|
||||||
#define __64BITS__
|
|
||||||
#else
|
|
||||||
#define __32BITS__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Set::Set()
|
Set::Set()
|
||||||
{
|
{
|
||||||
m_p_nArray = NULL;
|
m_p_nArray = NULL;
|
||||||
|
@ -55,16 +39,14 @@ Set::Set()
|
||||||
m_nSize = 0;
|
m_nSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy constructor
|
Set::Set(const Set& obj)
|
||||||
Set::Set(const Set& obj) {
|
{
|
||||||
m_p_nArray = NULL;
|
m_p_nArray = NULL;
|
||||||
setSize(obj.m_nSize);
|
setSize(obj.m_nSize);
|
||||||
|
|
||||||
// copy from the host to this array
|
// copy from the host to this array
|
||||||
for(int i=0; i<m_nArrayLen; i++) {
|
for (int i = 0; i < m_nArrayLen; i++)
|
||||||
m_p_nArray[i] = obj.m_p_nArray[i];
|
m_p_nArray[i] = obj.m_p_nArray[i];
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Set::Set(int size)
|
Set::Set(int size)
|
||||||
|
@ -72,198 +54,110 @@ Set::Set(int size)
|
||||||
m_p_nArray = NULL;
|
m_p_nArray = NULL;
|
||||||
m_nArrayLen = 0;
|
m_nArrayLen = 0;
|
||||||
m_nSize = 0;
|
m_nSize = 0;
|
||||||
if(size > 0) {
|
if (size > 0)
|
||||||
setSize(size);
|
setSize(size);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Set::~Set() {
|
Set::~Set()
|
||||||
if( (m_p_nArray != (&m_p_nArray_Static[0])) && (m_p_nArray != NULL))
|
{
|
||||||
|
if (m_p_nArray && m_p_nArray != &m_p_nArray_Static[0])
|
||||||
delete [] m_p_nArray;
|
delete [] m_p_nArray;
|
||||||
m_p_nArray = NULL;
|
m_p_nArray = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Set::clearExcess()
|
||||||
|
{
|
||||||
|
// now just ensure that no bits over the maximum size were set
|
||||||
|
#ifdef _LP64
|
||||||
|
long mask = 0x7FFFFFFFFFFFFFFF;
|
||||||
|
#else
|
||||||
|
long mask = 0x7FFFFFFF;
|
||||||
|
#endif
|
||||||
|
|
||||||
// /*
|
// the number of populated spaces in the higest-order array slot
|
||||||
// * This function should set the bit corresponding to index
|
// is: m_nSize % LONG_BITS, so the uppermost LONG_BITS -
|
||||||
// * to 1.
|
// m_nSize%64 bits should be cleared
|
||||||
// */
|
if ((m_nSize % LONG_BITS) != 0) {
|
||||||
|
for (int j = 0; j < 64 - (m_nSize & INDEX_MASK); j++) {
|
||||||
|
m_p_nArray[m_nArrayLen - 1] &= mask;
|
||||||
|
mask = mask >> 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// void Set::add(NodeID index)
|
|
||||||
// {
|
|
||||||
// assert(index<m_nSize && 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
|
* This function should set all the bits in the current set that are
|
||||||
* that are already set in the parameter set
|
* already set in the parameter set
|
||||||
*/
|
*/
|
||||||
void Set::addSet(const Set& set)
|
void
|
||||||
|
Set::addSet(const Set& set)
|
||||||
{
|
{
|
||||||
assert(getSize()==set.getSize());
|
assert(getSize()==set.getSize());
|
||||||
for(int i=0; i<m_nArrayLen; i++) {
|
for (int i = 0; i < m_nArrayLen; i++)
|
||||||
m_p_nArray[i] |= set.m_p_nArray[i];
|
m_p_nArray[i] |= set.m_p_nArray[i];
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function should randomly assign 1 to the bits in the set--
|
* This function should randomly assign 1 to the bits in the set--it
|
||||||
* it should not clear the bits bits first, though?
|
* should not clear the bits bits first, though?
|
||||||
*/
|
*/
|
||||||
void Set::addRandom()
|
void
|
||||||
|
Set::addRandom()
|
||||||
{
|
{
|
||||||
|
|
||||||
for(int i=0; i<m_nArrayLen; i++) {
|
for (int i = 0; i < m_nArrayLen; i++) {
|
||||||
m_p_nArray[i] |= random() ^ (random() << 4); // this ensures that all 32 bits are subject to random effects,
|
// this ensures that all 32 bits are subject to random effects,
|
||||||
// as RAND_MAX typically = 0x7FFFFFFF
|
// as RAND_MAX typically = 0x7FFFFFFF
|
||||||
|
m_p_nArray[i] |= random() ^ (random() << 4);
|
||||||
}
|
}
|
||||||
|
clearExcess();
|
||||||
// now just ensure that no bits over the maximum size were set
|
|
||||||
#ifdef __32BITS__
|
|
||||||
long mask = 0x7FFFFFFF;
|
|
||||||
|
|
||||||
// the number of populated spaces in the higest-order array slot is:
|
|
||||||
// m_nSize % 32, so the uppermost 32 - m_nSize%32 bits should be
|
|
||||||
// cleared
|
|
||||||
|
|
||||||
if((m_nSize % 32) != 0) {
|
|
||||||
for(int j=0; j<32-(m_nSize&0x01F); j++) {
|
|
||||||
m_p_nArray[m_nArrayLen-1] &= mask;
|
|
||||||
mask = mask >> 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<m_nSize && 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
|
* This function clears bits that are =1 in the parameter set
|
||||||
*/
|
*/
|
||||||
void Set::removeSet(const Set& set)
|
void
|
||||||
|
Set::removeSet(const Set& set)
|
||||||
{
|
{
|
||||||
|
assert(m_nSize == set.m_nSize);
|
||||||
assert(m_nSize==set.m_nSize);
|
for (int i = 0; i < m_nArrayLen; i++)
|
||||||
for(int i=0; i<m_nArrayLen; i++) {
|
m_p_nArray[i] &= ~set.m_p_nArray[i];
|
||||||
m_p_nArray[i] &= ~(set.m_p_nArray[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// /*
|
|
||||||
// * This function clears all bits in the set
|
|
||||||
// */
|
|
||||||
// void Set::clear()
|
|
||||||
// {
|
|
||||||
// for(int i=0; i<m_nArrayLen; i++) {
|
|
||||||
// m_p_nArray[i] = 0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this function sets all bits in the set
|
* this function sets all bits in the set
|
||||||
*/
|
*/
|
||||||
void Set::broadcast()
|
void
|
||||||
|
Set::broadcast()
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < m_nArrayLen; i++)
|
||||||
for(int i=0; i<m_nArrayLen; i++) {
|
|
||||||
m_p_nArray[i] = -1; // note that -1 corresponds to all 1's in 2's comp.
|
m_p_nArray[i] = -1; // note that -1 corresponds to all 1's in 2's comp.
|
||||||
}
|
|
||||||
|
|
||||||
// now just ensure that no bits over the maximum size were set
|
|
||||||
#ifdef __32BITS__
|
|
||||||
long mask = 0x7FFFFFFF;
|
|
||||||
|
|
||||||
// the number of populated spaces in the higest-order array slot is:
|
|
||||||
// m_nSize % 32, so the uppermost 32 - m_nSize%32 bits should be
|
|
||||||
// cleared
|
|
||||||
|
|
||||||
if((m_nSize % 32) != 0) {
|
|
||||||
for(int j=0; j<32-(m_nSize&0x01F); j++) {
|
|
||||||
m_p_nArray[m_nArrayLen-1] &= mask;
|
|
||||||
mask = mask >> 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__
|
|
||||||
|
|
||||||
|
clearExcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function returns the population count of 1's in the set
|
* This function returns the population count of 1's in the set
|
||||||
*/
|
*/
|
||||||
int Set::count() const
|
int
|
||||||
|
Set::count() const
|
||||||
{
|
{
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
long mask;
|
long mask;
|
||||||
for( int i=0; i<m_nArrayLen; i++) {
|
|
||||||
mask = (long) 0x01;
|
|
||||||
|
|
||||||
#ifdef __32BITS__
|
for (int i = 0; i < m_nArrayLen; i++) {
|
||||||
for( int j=0; j<32; j++) {
|
mask = (long)0x01;
|
||||||
if(m_p_nArray[i] & mask) counter++;
|
|
||||||
mask = mask << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
for (int j = 0; j < LONG_BITS; j++) {
|
||||||
|
// FIXME - significant performance loss when array
|
||||||
for( int j=0; j<64; j++) { // FIXME - significant performance loss when array population << 64
|
// population << LONG_BITS
|
||||||
if((m_p_nArray[i] & mask) != 0) {
|
if ((m_p_nArray[i] & mask) != 0) {
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
mask = mask << 1;
|
mask = mask << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __32BITS__
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return counter;
|
return counter;
|
||||||
|
@ -272,50 +166,38 @@ int Set::count() const
|
||||||
/*
|
/*
|
||||||
* This function checks for set equality
|
* This function checks for set equality
|
||||||
*/
|
*/
|
||||||
|
bool
|
||||||
bool Set::isEqual(const Set& set) const
|
Set::isEqual(const Set& set) const
|
||||||
{
|
{
|
||||||
assert(m_nSize==set.m_nSize);
|
assert(m_nSize == set.m_nSize);
|
||||||
|
|
||||||
for(int i=0;i<m_nArrayLen;i++) {
|
for (int i = 0; i < m_nArrayLen; i++)
|
||||||
if(m_p_nArray[i] != set.m_p_nArray[i]) {
|
if (m_p_nArray[i] != set.m_p_nArray[i])
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function returns the NodeID (int) of the
|
* This function returns the NodeID (int) of the least set bit
|
||||||
* least set bit
|
|
||||||
*/
|
*/
|
||||||
NodeID Set::smallestElement() const
|
NodeID
|
||||||
|
Set::smallestElement() const
|
||||||
{
|
{
|
||||||
assert(count() > 0);
|
assert(count() > 0);
|
||||||
long x;
|
long x;
|
||||||
for( int i=0; i<m_nArrayLen; i++) {
|
for (int i = 0; i < m_nArrayLen; i++) {
|
||||||
if(m_p_nArray[i]!=0) {
|
if (m_p_nArray[i] != 0) {
|
||||||
// the least-set bit must be in here
|
// the least-set bit must be in here
|
||||||
x = m_p_nArray[i];
|
x = m_p_nArray[i];
|
||||||
|
|
||||||
#ifdef __32BITS__
|
for (int j = 0; j < LONG_BITS; j++) {
|
||||||
for( int j=0; j<32; j++) {
|
if (x & (unsigned long)1) {
|
||||||
if(x & 0x00000001) {
|
return LONG_BITS * i + j;
|
||||||
return 32*i+j;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
x = x >> 1;
|
x = x >> 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.");
|
||||||
}
|
}
|
||||||
|
@ -329,45 +211,29 @@ NodeID Set::smallestElement() const
|
||||||
/*
|
/*
|
||||||
* this function returns true iff all bits are set
|
* this function returns true iff all bits are set
|
||||||
*/
|
*/
|
||||||
bool Set::isBroadcast() const
|
bool
|
||||||
|
Set::isBroadcast() const
|
||||||
{
|
{
|
||||||
// check the fully-loaded words by equal to 0xffffffff
|
// check the fully-loaded words by equal to 0xffffffff
|
||||||
// only the last word may not be fully loaded, it is not
|
// only the last word may not be fully loaded, it is not
|
||||||
// fully loaded iff m_nSize % 32 or 64 !=0 => fully loaded iff
|
// fully loaded iff m_nSize % 32 or 64 !=0 => fully loaded iff
|
||||||
// m_nSize % 32 or 64 == 0
|
// m_nSize % 32 or 64 == 0
|
||||||
|
|
||||||
#ifdef __32BITS__
|
int max = (m_nSize % LONG_BITS) == 0 ? m_nArrayLen : m_nArrayLen - 1;
|
||||||
for(int i=0; i< (((m_nSize % 32)==0) ? m_nArrayLen : m_nArrayLen-1); i++) {
|
for (int i = 0; i < max; i++) {
|
||||||
if(m_p_nArray[i]!=-1) {
|
if (m_p_nArray[i] != -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now check the last word, which may not be fully loaded
|
// now check the last word, which may not be fully loaded
|
||||||
long mask = 1;
|
long mask = 1;
|
||||||
for(int j=0; j< (m_nSize % 32); j++) {
|
for (int j = 0; j < (m_nSize % LONG_BITS); j++) {
|
||||||
if((mask & m_p_nArray[m_nArrayLen-1])==0) {
|
if ((mask & m_p_nArray[m_nArrayLen-1]) == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mask = mask << 1;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -375,147 +241,70 @@ bool Set::isBroadcast() const
|
||||||
/*
|
/*
|
||||||
* this function returns true iff no bits are set
|
* this function returns true iff no bits are set
|
||||||
*/
|
*/
|
||||||
bool Set::isEmpty() const
|
bool
|
||||||
|
Set::isEmpty() const
|
||||||
{
|
{
|
||||||
|
|
||||||
// here we can simply check if all = 0, since we ensure
|
// here we can simply check if all = 0, since we ensure
|
||||||
// that "extra slots" are all zero
|
// that "extra slots" are all zero
|
||||||
for(int i=0; i< m_nArrayLen ; i++) {
|
for (int i = 0; i < m_nArrayLen ; i++)
|
||||||
if(m_p_nArray[i]!=0) {
|
if (m_p_nArray[i])
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the logical OR of "this" set and orSet
|
// returns the logical OR of "this" set and orSet
|
||||||
Set Set::OR(const Set& orSet) const
|
Set
|
||||||
|
Set::OR(const Set& orSet) const
|
||||||
{
|
{
|
||||||
Set result(m_nSize);
|
Set result(m_nSize);
|
||||||
assert(m_nSize == orSet.m_nSize);
|
assert(m_nSize == orSet.m_nSize);
|
||||||
for(int i=0; i< m_nArrayLen; i++) {
|
for (int i = 0; i < m_nArrayLen; i++)
|
||||||
result.m_p_nArray[i] = m_p_nArray[i] | orSet.m_p_nArray[i];
|
result.m_p_nArray[i] = m_p_nArray[i] | orSet.m_p_nArray[i];
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the logical AND of "this" set and andSet
|
// returns the logical AND of "this" set and andSet
|
||||||
Set Set::AND(const Set& andSet) const
|
Set
|
||||||
|
Set::AND(const Set& andSet) const
|
||||||
{
|
{
|
||||||
Set result(m_nSize);
|
Set result(m_nSize);
|
||||||
assert(m_nSize == andSet.m_nSize);
|
assert(m_nSize == andSet.m_nSize);
|
||||||
|
|
||||||
for(int i=0; i< m_nArrayLen; i++) {
|
for (int i = 0; i < m_nArrayLen; i++) {
|
||||||
result.m_p_nArray[i] = m_p_nArray[i] & andSet.m_p_nArray[i];
|
result.m_p_nArray[i] = m_p_nArray[i] & andSet.m_p_nArray[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
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
|
* Returns false if a bit is set in the parameter set that is NOT set
|
||||||
* NOT set in this set
|
* in this set
|
||||||
*/
|
*/
|
||||||
bool Set::isSuperset(const Set& test) const
|
bool
|
||||||
|
Set::isSuperset(const Set& test) const
|
||||||
{
|
{
|
||||||
assert(m_nSize == test.m_nSize);
|
assert(m_nSize == test.m_nSize);
|
||||||
|
|
||||||
for(int i=0;i<m_nArrayLen;i++) {
|
for (int i = 0; i < m_nArrayLen; i++)
|
||||||
if(((test.m_p_nArray[i] & m_p_nArray[i]) | ~test.m_p_nArray[i]) != -1) {
|
if (((test.m_p_nArray[i] & m_p_nArray[i]) | ~test.m_p_nArray[i]) != -1)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /*
|
void
|
||||||
// * Returns true iff this bit is set
|
Set::setSize(int size)
|
||||||
// */
|
|
||||||
// bool Set::isElement(NodeID element) const
|
|
||||||
// {
|
|
||||||
// bool result;
|
|
||||||
|
|
||||||
// #ifdef __32BITS__
|
|
||||||
// result = ((m_p_nArray[element>>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<m_nSize;i++) {
|
|
||||||
// if(isElement(i)) match++;
|
|
||||||
// if(match==n) {
|
|
||||||
// return i;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return -1;
|
|
||||||
// */
|
|
||||||
// }
|
|
||||||
|
|
||||||
void Set::setSize(int size)
|
|
||||||
{
|
{
|
||||||
m_nSize = size;
|
m_nSize = size;
|
||||||
|
|
||||||
#ifdef __32BITS__
|
m_nArrayLen = m_nSize / LONG_BITS + ((m_nSize % LONG_BITS == 0) ? 0 : 1 );
|
||||||
m_nArrayLen = m_nSize/32 + ((m_nSize%32==0) ? 0 : 1 );
|
|
||||||
#else
|
|
||||||
m_nArrayLen = m_nSize/64 + ((m_nSize%64==0) ? 0 : 1 );
|
|
||||||
#endif // __32BITS__
|
|
||||||
|
|
||||||
// decide whether to use dynamic or static alloction
|
// decide whether to use dynamic or static alloction
|
||||||
if(m_nArrayLen<=NUMBER_WORDS_PER_SET) { // constant defined in RubySystem.hh
|
if (m_nArrayLen <= NUMBER_WORDS_PER_SET) {
|
||||||
|
// constant defined in RubySystem.hh
|
||||||
// its OK to use the static allocation, and it will
|
// its OK to use the static allocation, and it will
|
||||||
// probably be faster (as m_nArrayLen is already in the
|
// probably be faster (as m_nArrayLen is already in the
|
||||||
// cache and they will probably share the same cache line)
|
// cache and they will probably share the same cache line)
|
||||||
|
@ -523,15 +312,14 @@ void Set::setSize(int size)
|
||||||
// if switching from dyanamic to static allocation (which
|
// if switching from dyanamic to static allocation (which
|
||||||
// is probably rare, but why not be complete?), must delete
|
// is probably rare, but why not be complete?), must delete
|
||||||
// the dynamically allocated space
|
// the dynamically allocated space
|
||||||
if((m_p_nArray != NULL) && (m_p_nArray != &m_p_nArray_Static[0]))
|
if (m_p_nArray && m_p_nArray != &m_p_nArray_Static[0])
|
||||||
delete [] m_p_nArray;
|
delete [] m_p_nArray;
|
||||||
|
|
||||||
m_p_nArray = & m_p_nArray_Static[0];
|
m_p_nArray = &m_p_nArray_Static[0];
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// can't use static allocation...simply not enough room
|
// can't use static allocation...simply not enough room
|
||||||
// so dynamically allocate some space
|
// so dynamically allocate some space
|
||||||
if((m_p_nArray != NULL) && (m_p_nArray != &m_p_nArray_Static[0]))
|
if (m_p_nArray && m_p_nArray != &m_p_nArray_Static[0])
|
||||||
delete [] m_p_nArray;
|
delete [] m_p_nArray;
|
||||||
|
|
||||||
m_p_nArray = new long[m_nArrayLen];
|
m_p_nArray = new long[m_nArrayLen];
|
||||||
|
@ -540,41 +328,38 @@ void Set::setSize(int size)
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Set& Set::operator=(const Set& obj) {
|
Set&
|
||||||
if(this == &obj) {
|
Set::operator=(const Set& obj)
|
||||||
// do nothing
|
{
|
||||||
} else {
|
if (this != &obj) {
|
||||||
|
|
||||||
// resize this item
|
// resize this item
|
||||||
setSize(obj.getSize());
|
setSize(obj.getSize());
|
||||||
|
|
||||||
// copy the elements from obj to this
|
// copy the elements from obj to this
|
||||||
for(int i=0; i<m_nArrayLen; i++) {
|
for (int i = 0; i < m_nArrayLen; i++)
|
||||||
m_p_nArray[i] = obj.m_p_nArray[i];
|
m_p_nArray[i] = obj.m_p_nArray[i];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Set::print(std::ostream& out) const
|
void
|
||||||
|
Set::print(std::ostream& out) const
|
||||||
{
|
{
|
||||||
if(m_p_nArray==NULL) {
|
if (!m_p_nArray) {
|
||||||
out << "[Set {Empty}]";
|
out << "[Set {Empty}]";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buff[24];
|
char buff[24];
|
||||||
out << "[Set (" << m_nSize << ") 0x ";
|
out << "[Set (" << m_nSize << ") 0x ";
|
||||||
for (int i=m_nArrayLen-1; i>=0; i--) {
|
for (int i = m_nArrayLen - 1; i >= 0; i--) {
|
||||||
#ifdef __32BITS__
|
#ifdef _LP64
|
||||||
sprintf(buff,"%08X ",m_p_nArray[i]);
|
|
||||||
#else
|
|
||||||
sprintf(buff,"0x %016llX ", (long long)m_p_nArray[i]);
|
sprintf(buff,"0x %016llX ", (long long)m_p_nArray[i]);
|
||||||
|
#else
|
||||||
|
sprintf(buff,"%08X ", m_p_nArray[i]);
|
||||||
#endif // __32BITS__
|
#endif // __32BITS__
|
||||||
out << buff;
|
out << buff;
|
||||||
}
|
}
|
||||||
out << " ]";
|
out << " ]";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -27,118 +26,102 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Set.hh
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
*
|
|
||||||
* $Id: BigSet.hh 1.6 05/01/19 13:12:25-06:00 mikem@maya.cs.wisc.edu $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// modified by Dan Gibson on 05/20/05 to accomidate FASTER
|
// modified by Dan Gibson on 05/20/05 to accomidate FASTER
|
||||||
// >32 set lengths, using an array of ints w/ 32 bits/int
|
// >32 set lengths, using an array of ints w/ 32 bits/int
|
||||||
|
|
||||||
// NOTE: Never include this file directly, this should only be
|
#ifndef __MEM_RUBY_COMMON_SET_HH__
|
||||||
// included from Set.hh
|
#define __MEM_RUBY_COMMON_SET_HH__
|
||||||
|
|
||||||
#ifndef SET_H
|
|
||||||
#define SET_H
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "mem/ruby/system/System.hh"
|
#include "mem/ruby/system/System.hh"
|
||||||
#include "mem/ruby/common/Global.hh"
|
#include "mem/ruby/common/Global.hh"
|
||||||
#include "mem/gems_common/Vector.hh"
|
|
||||||
#include "mem/ruby/system/NodeID.hh"
|
#include "mem/ruby/system/NodeID.hh"
|
||||||
|
|
||||||
// gibson 05/20/05
|
class Set
|
||||||
// enum PresenceBit {NotPresent, Present};
|
{
|
||||||
|
private:
|
||||||
|
int m_nSize; // the number of bits in this set
|
||||||
|
int m_nArrayLen; // the number of 32-bit words that are
|
||||||
|
// held in the array
|
||||||
|
|
||||||
class Set {
|
// Changed 5/24/05 for static allocation of array
|
||||||
public:
|
// note that "long" corresponds to 32 bits on a 32-bit machine,
|
||||||
// Constructors
|
// 64 bits if the -m64 parameter is passed to g++, which it is
|
||||||
// creates and empty set
|
// for an AMD opteron under our configuration
|
||||||
|
|
||||||
|
long *m_p_nArray; // an word array to hold the bits in the set
|
||||||
|
long m_p_nArray_Static[NUMBER_WORDS_PER_SET];
|
||||||
|
|
||||||
|
static const int LONG_BITS = std::numeric_limits<long>::digits;
|
||||||
|
static const int INDEX_SHIFT = LONG_BITS == 64 ? 6 : 5;
|
||||||
|
static const int INDEX_MASK = (1 << INDEX_SHIFT) - 1;
|
||||||
|
|
||||||
|
void clearExcess();
|
||||||
|
|
||||||
|
public:
|
||||||
Set();
|
Set();
|
||||||
Set (int size);
|
Set(int size);
|
||||||
|
|
||||||
// used during the replay mechanism
|
|
||||||
// Set(const char *str);
|
|
||||||
|
|
||||||
Set(const Set& obj);
|
Set(const Set& obj);
|
||||||
Set& operator=(const Set& obj);
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
~Set();
|
~Set();
|
||||||
|
|
||||||
// Public Methods
|
Set& operator=(const Set& obj);
|
||||||
|
|
||||||
inline void add(NodeID index)
|
void
|
||||||
|
add(NodeID index)
|
||||||
{
|
{
|
||||||
#ifdef __32BITS__
|
m_p_nArray[index >> INDEX_SHIFT] |=
|
||||||
m_p_nArray[index>>5] |= (1 << (index & 0x01F));
|
(((unsigned long) 1) << (index & INDEX_MASK));
|
||||||
#else
|
|
||||||
m_p_nArray[index>>6] |= (((unsigned long) 1) << (index & 0x03F));
|
|
||||||
#endif // __32BITS__
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addSet(const Set& set);
|
void addSet(const Set& set);
|
||||||
void addRandom();
|
void addRandom();
|
||||||
|
|
||||||
inline void remove(NodeID index)
|
void
|
||||||
|
remove(NodeID index)
|
||||||
{
|
{
|
||||||
#ifdef __32BITS__
|
m_p_nArray[index >> INDEX_SHIFT] &=
|
||||||
m_p_nArray[index>>5] &= ~(0x00000001 << (index & 0x01F));
|
~(((unsigned long)1) << (index & INDEX_MASK));
|
||||||
#else
|
|
||||||
m_p_nArray[index>>6] &= ~(((unsigned long) 0x0000000000000001) << (index & 0x03F));
|
|
||||||
#endif // __32BITS__
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void removeSet(const Set& set);
|
void removeSet(const Set& set);
|
||||||
|
|
||||||
inline void clear() { for(int i=0; i<m_nArrayLen; i++) m_p_nArray[i] = 0; }
|
void
|
||||||
|
clear()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_nArrayLen; i++)
|
||||||
|
m_p_nArray[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void broadcast();
|
void broadcast();
|
||||||
int count() const;
|
int count() const;
|
||||||
bool isEqual(const Set& set) const;
|
bool isEqual(const Set& set) const;
|
||||||
|
|
||||||
Set OR(const Set& orSet) const; // return the logical OR of this set and orSet
|
// return the logical OR of this set and orSet
|
||||||
Set AND(const Set& andSet) const; // return the logical AND of this set and andSet
|
Set OR(const Set& orSet) const;
|
||||||
|
|
||||||
// Returns true if the intersection of the two sets is non-empty
|
// return the logical AND of this set and andSet
|
||||||
inline bool intersectionIsNotEmpty(const Set& other_set) const
|
Set AND(const Set& andSet) const;
|
||||||
{
|
|
||||||
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
|
// Returns true if the intersection of the two sets is empty
|
||||||
inline bool intersectionIsEmpty(const Set& other_set) const
|
bool
|
||||||
|
intersectionIsEmpty(const Set& other_set) const
|
||||||
{
|
{
|
||||||
for(int i=0; i< m_nArrayLen; i++) {
|
for (int i = 0; i < m_nArrayLen; i++)
|
||||||
if(m_p_nArray[i] & other_set.m_p_nArray[i]) {
|
if (m_p_nArray[i] & other_set.m_p_nArray[i])
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSuperset(const Set& test) const;
|
bool isSuperset(const Set& test) const;
|
||||||
bool isSubset(const Set& test) const { return test.isSuperset(*this); }
|
bool isSubset(const Set& test) const { return test.isSuperset(*this); }
|
||||||
|
|
||||||
inline bool isElement(NodeID element) const
|
bool
|
||||||
|
isElement(NodeID element) const
|
||||||
{
|
{
|
||||||
#ifdef __32BITS__
|
return (m_p_nArray[element>>INDEX_SHIFT] &
|
||||||
return ((m_p_nArray[element>>5] & (0x00000001 << (element & 0x01F)))!=0);
|
(((unsigned long)1) << (element & INDEX_MASK))) != 0;
|
||||||
#else
|
|
||||||
return ((m_p_nArray[element>>6] & (((unsigned long) 0x0000000000000001) << (element & 0x03F)))!=0);
|
|
||||||
#endif // __32BITS__
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isBroadcast() const;
|
bool isBroadcast() const;
|
||||||
|
@ -146,59 +129,28 @@ public:
|
||||||
|
|
||||||
NodeID smallestElement() const;
|
NodeID smallestElement() const;
|
||||||
|
|
||||||
// int size() const;
|
void setSize(int size);
|
||||||
void setSize (int size);
|
|
||||||
|
|
||||||
// get element for a index
|
NodeID
|
||||||
inline NodeID elementAt(int index) const
|
elementAt(int index) const
|
||||||
{
|
{
|
||||||
if(isElement(index)) return (NodeID) true;
|
if (isElement(index))
|
||||||
else return 0;
|
return (NodeID)true;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// gibson 05/20/05
|
|
||||||
int getSize() const { return m_nSize; }
|
int getSize() const { return m_nSize; }
|
||||||
|
|
||||||
// DEPRECATED METHODS
|
|
||||||
void addToSet(NodeID newElement) { add(newElement); } // Deprecated
|
|
||||||
void removeFromSet(NodeID newElement) { remove(newElement); } // Deprecated
|
|
||||||
void clearSet() { clear(); } // Deprecated
|
|
||||||
void setBroadcast() { broadcast(); } // Deprecated
|
|
||||||
bool presentInSet(NodeID element) const { return isElement(element); } // Deprecated
|
|
||||||
|
|
||||||
void print(std::ostream& out) const;
|
void print(std::ostream& out) const;
|
||||||
private:
|
|
||||||
// Private Methods
|
|
||||||
|
|
||||||
// Data Members (m_ prefix)
|
|
||||||
// gibson 05/20/05
|
|
||||||
// Vector<uint8> m_bits; // This is an vector of uint8 to reduce the size of the set
|
|
||||||
|
|
||||||
int m_nSize; // the number of bits in this set
|
|
||||||
int m_nArrayLen; // the number of 32-bit words that are held in the array
|
|
||||||
|
|
||||||
// Changed 5/24/05 for static allocation of array
|
|
||||||
// note that "long" corresponds to 32 bits on a 32-bit machine,
|
|
||||||
// 64 bits if the -m64 parameter is passed to g++, which it is
|
|
||||||
// for an AMD opteron under our configuration
|
|
||||||
|
|
||||||
long * m_p_nArray; // an word array to hold the bits in the set
|
|
||||||
long m_p_nArray_Static[NUMBER_WORDS_PER_SET];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Output operator declaration
|
inline std::ostream&
|
||||||
std::ostream& operator<<(std::ostream& out, const Set& obj);
|
operator<<(std::ostream& out, const Set& obj)
|
||||||
|
|
||||||
// ******************* Definitions *******************
|
|
||||||
|
|
||||||
// Output operator definition
|
|
||||||
extern inline
|
|
||||||
std::ostream& operator<<(std::ostream& out, const Set& obj)
|
|
||||||
{
|
{
|
||||||
obj.print(out);
|
obj.print(out);
|
||||||
out << std::flush;
|
out << std::flush;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //SET_H
|
#endif // __MEM_RUBY_COMMON_SET_HH__
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue