using System;
using System.Collections;
using System.Linq;
using System.Runtime.Serialization;
namespace BitsetsNET
{
public class UncompressedBitArray : IBitset
{
private BitArray array;
public UncompressedBitArray() { }
public UncompressedBitArray(UncompressedBitArray copy)
{
array = new BitArray(copy.array);
}
public UncompressedBitArray(int[] indices) : this(indices, indices.Max()) { }
public UncompressedBitArray(int[] indices, int capacity)
{
int length = capacity;
array = new BitArray(length);
foreach (int index in indices)
{
array.Set(index, true);
}
}
public int Length
{
get
{
return array.Length;
}
}
///
/// Creates a new bitset that is the bitwise AND of this bitset with another
///
/// Other bitset
/// A new IBitset
public IBitset And(IBitset otherSet)
{
IBitset result = this.Clone();
result.AndWith(otherSet);
return result;
}
///
/// Performs an in-place intersection of two Roaring Bitsets.
///
/// the second Roaring Bitset to intersect
public void AndWith(IBitset otherSet)
{
array = array.And(((UncompressedBitArray)otherSet).array);
}
///
/// Create a new bitset that is a deep copy of this one.
///
/// The cloned bitset
public IBitset Clone()
{
return new UncompressedBitArray(this);
}
///
/// Return whether the given index is a member of this set
///
/// the index to test
/// True if the index is a member of this set
public bool Get(int index)
{
return array.Get(index);
}
///
/// Creates a new bitset that is the bitwise OR of this bitset with another bitset.
///
/// Other bitset
/// A new IBitset
public IBitset Or(IBitset otherSet)
{
IBitset result = this.Clone();
result.OrWith(otherSet);
return result;
}
///
/// Computes the in-place bitwise OR of this bitset with another bitset.
///
/// Other bitset
public void OrWith(IBitset otherSet)
{
array = array.Or(((UncompressedBitArray)otherSet).array);
}
///
/// If the value is true and given index is not in the set add it. If
/// the value is false and the index is in the set remove it. Otherwise,
/// do nothing.
///
/// the index to set
public void Set(int index, bool value)
{
array.Set(index, value);
}
///
/// Sets all bits in the array to the specified value
///
///
public void SetAll(bool value)
{
array.SetAll(value);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotImplementedException();
}
public IEnumerator GetEnumerator()
{
for (int i = 0; i < this.array.Length; i++)
{
if (this.array.Get(i) == true)
{
yield return i;
}
}
}
///
/// Returns a new bitset that consists of all elements that are not
/// in this bitset.
///
/// The new bitset
public IBitset Not()
{
var newSet = new UncompressedBitArray();
newSet.array = array.Not();
return newSet;
}
///
/// The number of members in the set
///
/// an integer for the number of members in the set
public int Cardinality()
{
int rtnValue = 0;
for (int i = 0; i < array.Length; i++)
{
if (array[i]) rtnValue += 1;
}
return rtnValue;
}
///
/// For indices in the range [start, end) add the index to the set if
/// the value is true, otherwise remove it.
///
/// the index to start from (inclusive)
/// the index to stop at (exclusive)
public void Set(int start, int end, bool value)
{
for (int i = start; i <= end; i++ )
{
array.Set(i, value);
}
}
///
/// If the given index is not in the set add it, otherwise remove it.
///
/// the index to flip
public void Flip(int index)
{
array[index] = !array[index];
}
///
/// For indices in the range [start, end) add the index to the set if
/// it does not exists, otherwise remove it.
///
/// the index to start from (inclusive)
/// the index to stop at (exclusive)
public void Flip(int start, int end)
{
for (int i = start; i < end; i++)
{
Flip(i);
}
}
///
/// Creates a new IBitSet that has the members of this BitSet that are
/// not members of the other bitset
///
/// The other bitset
/// a new IBitSet
public IBitset Difference(IBitset otherSet)
{
UncompressedBitArray workset = null;
if (otherSet is UncompressedBitArray)
{
workset = (UncompressedBitArray)otherSet;
}
else
{
throw new InvalidOperationException("otherSet is not an UncompressedBitArray");
}
UncompressedBitArray newArray = (UncompressedBitArray) this.Clone();
for (int i = 0; i < workset.array.Length; i++)
{
if (workset.array[i] && i < this.Length)
{
newArray.Set(i, false);
}
}
return newArray;
}
public BitArray ToBitArray()
{
return new BitArray(this.array);
}
public void Serialize(System.IO.Stream stream)
{
throw new NotImplementedException();
}
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
UncompressedBitArray compare = (UncompressedBitArray)obj;
bool equalLength = (this.Length == compare.Length);
if (equalLength)
{
for (int i = 0; i < this.Length; i++)
{
if (this.array.Get(i) != compare.array.Get(i))
{
equalLength = false;
}
}
}
return equalLength;
}
public override int GetHashCode()
{
unchecked
{
int hash = Length;
for (int i = 0; i < Length; i++)
{
hash = 17 * hash + array.Get(i).GetHashCode();
}
return hash;
}
}
}
}