1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
|
//------------------------------------------------------------------------------
// <copyright file="BitSet.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">Microsoft</owner>
//------------------------------------------------------------------------------
namespace System.Xml.Schema {
using System.Text;
using System.Diagnostics;
internal sealed class BitSet {
private const int bitSlotShift = 5;
private const int bitSlotMask = (1 << bitSlotShift) - 1;
private int count;
private uint[] bits;
private BitSet() {
}
public BitSet(int count) {
this.count = count;
bits = new uint[Subscript(count + bitSlotMask)];
}
public int Count {
get { return count; }
}
public bool this[int index] {
get {
return Get(index);
}
}
public void Clear() {
int bitsLength = bits.Length;
for (int i = bitsLength; i-- > 0 ;) {
bits[i] = 0;
}
}
public void Clear(int index) {
int nBitSlot = Subscript(index);
EnsureLength(nBitSlot + 1);
bits[nBitSlot] &= ~((uint)1 << (index & bitSlotMask));
}
public void Set(int index) {
int nBitSlot = Subscript(index);
EnsureLength(nBitSlot + 1);
bits[nBitSlot] |= (uint)1 << (index & bitSlotMask);
}
public bool Get(int index) {
bool fResult = false;
if (index < count) {
int nBitSlot = Subscript(index);
fResult = ((bits[nBitSlot] & (1 << (index & bitSlotMask))) != 0);
}
return fResult;
}
public int NextSet(int startFrom) {
Debug.Assert(startFrom >= -1 && startFrom <= count);
int offset = startFrom + 1;
if (offset == count) {
return -1;
}
int nBitSlot = Subscript(offset);
offset &= bitSlotMask;
uint word = bits[nBitSlot] >> offset;
// locate non-empty slot
while (word == 0) {
if ((++ nBitSlot) == bits.Length ) {
return -1;
}
offset = 0;
word = bits[nBitSlot];
}
while ((word & (uint)1) == 0) {
word >>= 1;
offset ++;
}
return (nBitSlot << bitSlotShift) + offset;
}
public void And(BitSet other) {
/*
* Need to synchronize both this and other->
* This might lead to deadlock if one thread grabs them in one order
* while another thread grabs them the other order.
* Use a trick from Doug Lea's book on concurrency,
* somewhat complicated because BitSet overrides hashCode().
*/
if (this == other) {
return;
}
int bitsLength = bits.Length;
int setLength = other.bits.Length;
int n = (bitsLength > setLength) ? setLength : bitsLength;
for (int i = n ; i-- > 0 ;) {
bits[i] &= other.bits[i];
}
for (; n < bitsLength ; n++) {
bits[n] = 0;
}
}
public void Or(BitSet other) {
if (this == other) {
return;
}
int setLength = other.bits.Length;
EnsureLength(setLength);
for (int i = setLength; i-- > 0 ;) {
bits[i] |= other.bits[i];
}
}
public override int GetHashCode() {
int h = 1234;
for (int i = bits.Length; --i >= 0;) {
h ^= (int)bits[i] * (i + 1);
}
return(int)((h >> 32) ^ h);
}
public override bool Equals(object obj) {
// assume the same type
if (obj != null) {
if (this == obj) {
return true;
}
BitSet other = (BitSet) obj;
int bitsLength = bits.Length;
int setLength = other.bits.Length;
int n = (bitsLength > setLength) ? setLength : bitsLength;
for (int i = n ; i-- > 0 ;) {
if (bits[i] != other.bits[i]) {
return false;
}
}
if (bitsLength > n) {
for (int i = bitsLength ; i-- > n ;) {
if (bits[i] != 0) {
return false;
}
}
}
else {
for (int i = setLength ; i-- > n ;) {
if (other.bits[i] != 0) {
return false;
}
}
}
return true;
}
return false;
}
public BitSet Clone() {
BitSet newset = new BitSet();
newset.count = count;
newset.bits = (uint[])bits.Clone();
return newset;
}
public bool IsEmpty {
get {
uint k = 0;
for (int i = 0; i < bits.Length; i++) {
k |= bits[i];
}
return k == 0;
}
}
public bool Intersects(BitSet other) {
int i = Math.Min(this.bits.Length, other.bits.Length);
while (--i >= 0) {
if ((this.bits[i] & other.bits[i]) != 0) {
return true;
}
}
return false;
}
private int Subscript(int bitIndex) {
return bitIndex >> bitSlotShift;
}
private void EnsureLength(int nRequiredLength) {
/* Doesn't need to be synchronized because it's an internal method. */
if (nRequiredLength > bits.Length) {
/* Ask for larger of doubled size or required size */
int request = 2 * bits.Length;
if (request < nRequiredLength)
request = nRequiredLength;
uint[] newBits = new uint[request];
Array.Copy(bits, newBits, bits.Length);
bits = newBits;
}
}
#if DEBUG
public void Dump(StringBuilder bb) {
for (int i = 0; i < count; i ++) {
bb.Append( Get(i) ? "1" : "0");
}
}
#endif
};
}
|