protected FastSparseBitArray(FastSparseBitArray other)
 {
     keys       = (int[])other.keys.Clone();
     values     = (ulong[])other.values.Clone();
     maxUsedPos = other.maxUsedPos;
     itemSum    = other.itemSum;
 }
        public void Release(FastSparseBitArray array)
        {
            if (maxPosUsed == pool.Length)
            {
                return;
            }

            array.Clear();
            pool[maxPosUsed] = array;
            maxPosUsed++;
        }
        public FastSparseBitArray Xor(FastSparseBitArray other)
        {
            FastSparseBitArray res = new FastSparseBitArray();
            int pos      = 0;
            int otherPos = 0;

            while ((pos < maxUsedPos) || (otherPos < other.maxUsedPos))
            {
                int   key;
                ulong val;

                if (otherPos == other.maxUsedPos)
                {
                    key = keys[pos];
                    val = values[pos];
                    pos++;
                }
                else if (pos == maxUsedPos)
                {
                    key = other.keys[otherPos];
                    val = other.values[otherPos];
                    otherPos++;
                }
                else if (keys[pos] < other.keys[otherPos])
                {
                    key = keys[pos];
                    val = values[pos];
                    pos++;
                }
                else if (keys[pos] > other.keys[otherPos])
                {
                    key = other.keys[otherPos];
                    val = other.values[otherPos];
                    otherPos++;
                }
                else
                {
                    key = keys[pos];
                    val = values[pos] ^ other.values[otherPos];
                    pos++;
                    otherPos++;
                }

                res.Insert(res.maxUsedPos, key);
                res.values[res.maxUsedPos - 1] = val;
            }

            return(res);
        }
        public FastSparseBitArray And(FastSparseBitArray other)
        {
            FastSparseBitArray res = FastSparseBitArrayPool.Instance.Allocate();             //new FastSparseBitArray(Math.Min(maxUsedPos,other.maxUsedPos)*BITS_IN_ULONG);

            int pos            = 0;
            int otherPos       = 0;
            int itemCount      = maxUsedPos;
            int otherItemCount = other.maxUsedPos;

            while ((pos < itemCount) && (otherPos < otherItemCount))
            {
                if (keys[pos] < other.keys[otherPos])
                {
                    pos++;
                }
                else if (keys[pos] > other.keys[otherPos])
                {
                    otherPos++;
                }
                else
                {
                    if ((values[pos] & other.values[otherPos]) != 0)
                    {
                        if (res.keys.Length <= res.maxUsedPos + 1)
                        {
                            int[]   newKeys   = new int[res.keys.Length * 2];
                            ulong[] newValues = new ulong[res.keys.Length * 2];

                            res.keys.CopyTo(newKeys, 0);
                            res.values.CopyTo(newValues, 0);
                            res.keys   = newKeys;
                            res.values = newValues;
                        }

                        res.keys[res.maxUsedPos] = keys[pos];
                        res.maxUsedPos++;
//						res.Insert(res.maxUsedPos, keys[pos]);
                        res.values[res.maxUsedPos - 1] = (values[pos] & other.values[otherPos]);
                    }
                    pos++;
                    otherPos++;
                }
            }

            return(res);
        }
        public int CompareTo(object obj)
        {
            FastSparseBitArray other = (FastSparseBitArray)obj;

            int otherPos = other.maxUsedPos - 1;
            int pos      = maxUsedPos - 1;

            while ((pos >= 0) && (otherPos >= 0))
            {
                if (keys[pos] > other.keys[otherPos])
                {
                    return(1);
                }

                if (keys[pos] < other.keys[otherPos])
                {
                    return(-1);
                }

                if (values[pos] > other.values[otherPos])
                {
                    return(1);
                }
                if (values[pos] < other.values[otherPos])
                {
                    return(-1);
                }

                pos--;
                otherPos--;
            }

            if ((pos == -1) && (otherPos == -1))
            {
                return(0);
            }

            if (otherPos == -1)
            {
                return(1);
            }

            return(-1);
        }
        // a.AndNot(b) == a And !b
        public FastSparseBitArray AndNot(FastSparseBitArray other)
        {
            FastSparseBitArray res = new FastSparseBitArray();

            int pos            = 0;
            int otherPos       = 0;
            int itemCount      = maxUsedPos;
            int otherItemCount = other.maxUsedPos;

            while ((pos < itemCount) && (otherPos < otherItemCount))
            {
                if (keys[pos] < other.keys[otherPos])
                {
                    res.Insert(res.maxUsedPos, keys[pos]);
                    res.values[res.maxUsedPos - 1] = values[pos];
                    pos++;
                }
                else if (keys[pos] > other.keys[otherPos])
                {
                    otherPos++;
                }
                else
                {
                    if ((values[pos] & (~other.values[otherPos])) != 0)
                    {
                        res.Insert(res.maxUsedPos, keys[pos]);
                        res.values[res.maxUsedPos - 1] = (values[pos] & (~other.values[otherPos]));
                    }
                    pos++;
                    otherPos++;
                }
            }

            while (pos < itemCount)
            {
                res.Insert(res.maxUsedPos, keys[pos]);
                res.values[res.maxUsedPos - 1] = values[pos];
                pos++;
            }

            return(res);
        }
        public bool IsContaining(FastSparseBitArray other)
        {
            int pos        = 0;
            int otherPos   = 0;
            int count      = maxUsedPos;
            int otherCount = other.maxUsedPos;

            while ((pos < count) && (otherPos < otherCount))
            {
                if (keys[pos] > other.keys[otherPos])
                {
                    return(false);
                }

                if (keys[pos] < other.keys[otherPos])
                {
                    pos++;
                    continue;
                }

                if ((values[pos] & other.values[otherPos]) != other.values[otherPos])
                {
                    return(false);
                }

                pos++;
                otherPos++;
            }

            if ((pos == count) && (otherPos < otherCount))
            {
                return(false);
            }

            return(true);
        }
 public bool IsOneItemDiff(FastSparseBitArray other)
 {
     return(Xor(other).CountElements() == 1);
 }