internal void Delete(int oldRecord)
        {
            if (oldRecord == -1)
            {
                return;
            }

            int index = FindIndexExact(oldRecord);

            if (index != -1)
            {
                if (know_have_duplicates)
                {
                    int c1 = 1;
                    int c2 = 1;

                    if (index > 0)
                    {
                        c1 = Key.CompareRecords(_array [index - 1], oldRecord);
                    }
                    if (index < _size - 1)
                    {
                        c2 = Key.CompareRecords(_array [index + 1], oldRecord);
                    }

                    if (c1 == 0 ^ c2 == 0)
                    {
                        know_have_duplicates = know_no_duplicates = false;
                    }
                }
                Remove(index);
            }
        }
        private int Partition(int [] a, int p, int r)
        {
            int x = a [p];
            int i = p - 1;
            int j = r + 1;

            while (true)
            {
                // decrement upper limit while values are greater then border value
                do
                {
                    j--;
                }while (Key.CompareRecords(a [j], x) > 0);

                do
                {
                    i++;
                }while (Key.CompareRecords(a [i], x) < 0);

                if (i < j)
                {
                    int tmp = a [j];
                    a [j] = a [i];
                    a [i] = tmp;
                }
                else
                {
                    return(j);
                }
            }
        }
        /*
         * Returns array of indexes of the records inside the index that equal to the record supplied
         * in the meaning of index key, or empty list if no equal records found.
         */
        internal int [] FindAllIndexes(int record)
        {
            int index = FindIndex(record);

            if (index == -1)
            {
                return(empty);
            }

            int startIndex = index++;
            int endIndex   = index;

            for (; startIndex >= 0 && Key.CompareRecords(_array [startIndex], record) == 0; startIndex--)
            {
            }
            for (; endIndex < _size && Key.CompareRecords(_array [endIndex], record) == 0; endIndex++)
            {
            }

            int length = endIndex - startIndex - 1;

            int [] indexes = new int [length];

            for (int i = 0; i < length; i++)
            {
                indexes [i] = ++startIndex;
            }

            return(indexes);
        }
Beispiel #4
0
        internal void Delete(int oldRecord)
        {
            if (oldRecord == -1)
            {
                return;
            }

            int index = FindIndexExact(oldRecord);

            if (index != -1)
            {
                if (_hasDuplicates == IndexDuplicatesState.True)
                {
                    int c1 = 1;
                    int c2 = 1;

                    if (index > 0)
                    {
                        c1 = Key.CompareRecords(Array [index - 1], oldRecord);
                    }
                    if (index < Size - 1)
                    {
                        c2 = Key.CompareRecords(Array [index + 1], oldRecord);
                    }

                    if (c1 == 0 ^ c2 == 0)
                    {
                        _hasDuplicates = IndexDuplicatesState.Unknown;
                    }
                }
                Remove(index);
            }
        }
        private void MergeSort(int [] from, int [] to, int p, int r)
        {
            int q = (p + r) >> 1;

            if (q == p)
            {
                return;
            }

            MergeSort(to, from, p, q);
            MergeSort(to, from, q, r);

            // merge
            for (int middle = q, current = p;;)
            {
                int res = Key.CompareRecords(from[p], from[q]);
                if (res > 0)
                {
                    to [current++] = from [q++];

                    if (q == r)
                    {
                        while (p < middle)
                        {
                            to [current++] = from [p++];
                        }
                        break;
                    }
                }
                else
                {
                    if (res == 0)
                    {
                        know_have_duplicates = true;
                    }

                    to [current++] = from [p++];

                    if (p == middle)
                    {
                        while (q < r)
                        {
                            to [current++] = from [q++];
                        }
                        break;
                    }
                }
            }
        }
        private void Add(DataRow row, int newRecord)
        {
            int newIdx;

            if (newRecord < 0 || !Key.CanContain(newRecord))
            {
                return;
            }

            if (_size == 0)
            {
                newIdx = 0;
            }
            else
            {
                newIdx = LazyBinarySearch(_array, 0, _size - 1, newRecord);
                // if newl value is greater - insert afer old value
                // else - insert before old value
                if (Key.CompareRecords(_array [newIdx], newRecord) < 0)
                {
                    newIdx++;
                }
            }

            Insert(newIdx, newRecord);

            int c1 = 1;
            int c2 = 1;

            if (!know_have_duplicates)
            {
                if (newIdx > 0)
                {
                    c1 = Key.CompareRecords(_array [newIdx - 1], newRecord);
                }
                if (newIdx < _size - 1)
                {
                    c2 = Key.CompareRecords(_array [newIdx + 1], newRecord);
                }

                if (c1 == 0 || c2 == 0)
                {
                    know_have_duplicates = true;
                }
            }
        }
Beispiel #7
0
        private void Add(DataRow row, int newRecord)
        {
            int newIdx;

            if (newRecord < 0 || !Key.CanContain(newRecord))
            {
                return;
            }

            if (Size == 0)
            {
                newIdx = 0;
            }
            else
            {
                newIdx = LazyBinarySearch(Array, 0, Size - 1, newRecord);
                // if newl value is greater - insert afer old value
                // else - insert before old value
                if (Key.CompareRecords(Array [newIdx], newRecord) < 0)
                {
                    newIdx++;
                }
            }

            Insert(newIdx, newRecord);

            int c1 = 1;
            int c2 = 1;

            if (!(_hasDuplicates == IndexDuplicatesState.True))
            {
                if (newIdx > 0)
                {
                    c1 = Key.CompareRecords(Array [newIdx - 1], newRecord);
                }
                if (newIdx < Size - 1)
                {
                    c2 = Key.CompareRecords(Array [newIdx + 1], newRecord);
                }

                if (c1 == 0 || c2 == 0)
                {
                    _hasDuplicates = IndexDuplicatesState.True;
                }
            }
        }
        internal DataRow [] GetDistinctRows()
        {
            ArrayList list = new ArrayList();

            list.Add(Key.Table.RecordCache [_array [0]]);
            int currRecord = _array [0];

            for (int i = 1; i < _size; ++i)
            {
                if (Key.CompareRecords(currRecord, _array [i]) == 0)
                {
                    continue;
                }
                list.Add(Key.Table.RecordCache [_array [i]]);
                currRecord = _array [i];
            }
            return((DataRow [])list.ToArray(typeof(DataRow)));
        }
        // Lazy binary search only returns the cell number the search finished in,
        // but does not checks that the correct value was actually found
        private int LazyBinarySearch(int [] a, int p, int r, int b)
        {
            if (p == r)
            {
                return(p);
            }

            int q = (p + r) >> 1;

            int compare = Key.CompareRecords(a [q], b);

            if (compare < 0)
            {
                return(LazyBinarySearch(a, q + 1, r, b));
            }
            else if (compare > 0)
            {
                return(LazyBinarySearch(a, p, q, b));
            }
            else
            {
                return(q);
            }
        }
        private int BinarySearch(int [] a, int p, int r, int b)
        {
            int i = LazyBinarySearch(a, p, r, b);

            return((Key.CompareRecords(a [i], b) == 0) ? i : -1);
        }
        internal void Update(DataRow row, int oldRecord, DataRowVersion oldVersion, DataRowState oldState)
        {
            bool contains  = Key.ContainsVersion(oldState, oldVersion);
            int  newRecord = Key.GetRecord(row);

            // the record did not appeared in the index before update
            if (oldRecord == -1 || _size == 0 || !contains)
            {
                if (newRecord >= 0)
                {
                    if (FindIndexExact(newRecord) < 0)
                    {
                        Add(row, newRecord);
                    }
                }
                return;
            }

            // the record will not appeare in the index after update
            if (newRecord < 0 || !Key.CanContain(newRecord))
            {
                Delete(oldRecord);
                return;
            }

            int oldIdx = FindIndexExact(oldRecord);

            if (oldIdx == -1)
            {
                Add(row, newRecord);
                return;
            }

            int newIdx = -1;
            int compare = Key.CompareRecords(_array [oldIdx], newRecord);
            int start, end;

            int c1 = 1;
            int c2 = 1;

            if (compare == 0)
            {
                if (_array [oldIdx] == newRecord)
                {
                    // we deal with the same record that didn't change
                    // in the context of current index.
                    // so , do nothing.
                    return;
                }
            }
            else
            {
                if (know_have_duplicates)
                {
                    if (oldIdx > 0)
                    {
                        c1 = Key.CompareRecords(_array [oldIdx - 1], newRecord);
                    }
                    if (oldIdx < _size - 1)
                    {
                        c2 = Key.CompareRecords(_array [oldIdx + 1], newRecord);
                    }

                    if ((c1 == 0 ^ c2 == 0) && compare != 0)
                    {
                        know_have_duplicates = know_no_duplicates = false;
                    }
                }
            }

            if ((oldIdx == 0 && compare > 0) || (oldIdx == (_size - 1) && compare < 0) || (compare == 0))
            {
                // no need to switch cells
                newIdx = oldIdx;
            }
            else
            {
                if (compare < 0)
                {
                    // search after the old place
                    start = oldIdx + 1;
                    end   = _size - 1;
                }
                else
                {
                    // search before the old palce
                    start = 0;
                    end   = oldIdx - 1;
                }

                newIdx = LazyBinarySearch(_array, start, end, newRecord);

                if (oldIdx < newIdx)
                {
                    System.Array.Copy(_array, oldIdx + 1, _array, oldIdx, newIdx - oldIdx);
                    if (Key.CompareRecords(_array [newIdx], newRecord) > 0)
                    {
                        --newIdx;
                    }
                }
                else if (oldIdx > newIdx)
                {
                    System.Array.Copy(_array, newIdx, _array, newIdx + 1, oldIdx - newIdx);
                    if (Key.CompareRecords(_array [newIdx], newRecord) < 0)
                    {
                        ++newIdx;
                    }
                }
            }
            _array[newIdx] = newRecord;

            if (compare != 0)
            {
                if (!know_have_duplicates)
                {
                    if (newIdx > 0)
                    {
                        c1 = Key.CompareRecords(_array [newIdx - 1], newRecord);
                    }
                    if (newIdx < _size - 1)
                    {
                        c2 = Key.CompareRecords(_array [newIdx + 1], newRecord);
                    }

                    if (c1 == 0 || c2 == 0)
                    {
                        know_have_duplicates = true;
                    }
                }
            }
        }