1 //------------------------------------------------------------------------------
2 // <copyright file="BitSet.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 //------------------------------------------------------------------------------
8 namespace System.Xml.Schema {
11 using System.Diagnostics;
13 internal sealed class BitSet {
14 private const int bitSlotShift = 5;
15 private const int bitSlotMask = (1 << bitSlotShift) - 1;
23 public BitSet(int count) {
25 bits = new uint[Subscript(count + bitSlotMask)];
32 public bool this[int index] {
39 int bitsLength = bits.Length;
40 for (int i = bitsLength; i-- > 0 ;) {
45 public void Clear(int index) {
46 int nBitSlot = Subscript(index);
47 EnsureLength(nBitSlot + 1);
48 bits[nBitSlot] &= ~((uint)1 << (index & bitSlotMask));
51 public void Set(int index) {
52 int nBitSlot = Subscript(index);
53 EnsureLength(nBitSlot + 1);
54 bits[nBitSlot] |= (uint)1 << (index & bitSlotMask);
58 public bool Get(int index) {
61 int nBitSlot = Subscript(index);
62 fResult = ((bits[nBitSlot] & (1 << (index & bitSlotMask))) != 0);
67 public int NextSet(int startFrom) {
68 Debug.Assert(startFrom >= -1 && startFrom <= count);
69 int offset = startFrom + 1;
70 if (offset == count) {
73 int nBitSlot = Subscript(offset);
74 offset &= bitSlotMask;
75 uint word = bits[nBitSlot] >> offset;
76 // locate non-empty slot
78 if ((++ nBitSlot) == bits.Length ) {
82 word = bits[nBitSlot];
84 while ((word & (uint)1) == 0) {
88 return (nBitSlot << bitSlotShift) + offset;
91 public void And(BitSet other) {
93 * Need to synchronize both this and other->
94 * This might lead to deadlock if one thread grabs them in one order
95 * while another thread grabs them the other order.
96 * Use a trick from Doug Lea's book on concurrency,
97 * somewhat complicated because BitSet overrides hashCode().
102 int bitsLength = bits.Length;
103 int setLength = other.bits.Length;
104 int n = (bitsLength > setLength) ? setLength : bitsLength;
105 for (int i = n ; i-- > 0 ;) {
106 bits[i] &= other.bits[i];
108 for (; n < bitsLength ; n++) {
114 public void Or(BitSet other) {
118 int setLength = other.bits.Length;
119 EnsureLength(setLength);
120 for (int i = setLength; i-- > 0 ;) {
121 bits[i] |= other.bits[i];
125 public override int GetHashCode() {
127 for (int i = bits.Length; --i >= 0;) {
128 h ^= (int)bits[i] * (i + 1);
130 return(int)((h >> 32) ^ h);
134 public override bool Equals(object obj) {
135 // assume the same type
140 BitSet other = (BitSet) obj;
142 int bitsLength = bits.Length;
143 int setLength = other.bits.Length;
144 int n = (bitsLength > setLength) ? setLength : bitsLength;
145 for (int i = n ; i-- > 0 ;) {
146 if (bits[i] != other.bits[i]) {
150 if (bitsLength > n) {
151 for (int i = bitsLength ; i-- > n ;) {
158 for (int i = setLength ; i-- > n ;) {
159 if (other.bits[i] != 0) {
169 public BitSet Clone() {
170 BitSet newset = new BitSet();
171 newset.count = count;
172 newset.bits = (uint[])bits.Clone();
177 public bool IsEmpty {
180 for (int i = 0; i < bits.Length; i++) {
187 public bool Intersects(BitSet other) {
188 int i = Math.Min(this.bits.Length, other.bits.Length);
190 if ((this.bits[i] & other.bits[i]) != 0) {
197 private int Subscript(int bitIndex) {
198 return bitIndex >> bitSlotShift;
201 private void EnsureLength(int nRequiredLength) {
202 /* Doesn't need to be synchronized because it's an internal method. */
203 if (nRequiredLength > bits.Length) {
204 /* Ask for larger of doubled size or required size */
205 int request = 2 * bits.Length;
206 if (request < nRequiredLength)
207 request = nRequiredLength;
208 uint[] newBits = new uint[request];
209 Array.Copy(bits, newBits, bits.Length);
215 public void Dump(StringBuilder bb) {
216 for (int i = 0; i < count; i ++) {
217 bb.Append( Get(i) ? "1" : "0");