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); }
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; } } }
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; } } } }