public void AndWith(IBitset otherSet)
{
RLEBitset otherRLESet = (RLEBitset)otherSet; // cast to an RLEBitset
List<Run> runsA = this.runArray;
List<Run> runsB = otherRLESet.runArray;
int i = 0;
int j = 0;
while (i < runsA.Count && j < runsB.Count)
{
int x = runsA[i].StartIndex;
int y = runsA[i].EndIndex;
int w = runsB[j].StartIndex;
int z = runsB[j].EndIndex;
if (x < w)
{
if (y < w)
{
runsA.RemoveAt(i);
}
else // (y >= w)
{
// crops the current run in runsA from the left to align with
// the start of the current run in runsB
Run ithRun = runsA[i];
ithRun.StartIndex = w;
runsA[i] = ithRun;
var what = this.runArray[i];
if (y <= z)
{
i++;
}
else // (y > z )
{
// splits the run from runsA into two runs
Run newRun = new Run(z + 1, y);
Run newRun2 = runsA[i];
newRun2.EndIndex = z;
runsA[i] = newRun2;
runsA.Insert(i + 1, newRun);
i++;
j++;
}
}
}
else // (x >= w)
{
if (y <= z)
{
i++;
}
else // (y > z)
{
if (x <= z)
{
// splits the run from runsA into two runs
Run newRun = new Run(z + 1, y);
Run newRun2 = runsA[i];
newRun2.EndIndex = z;
runsA[i] = newRun2;
runsA.Insert(i + 1, newRun);
i++;
j++;
}
else
{
j++;
}
}
}
}
//this truncates runsA if we've considered all of the runs in runsB
this.runArray = this.runArray.Take(i).ToList();
}