TObjectdataset deletion failure after sorting

Issue #215 on hold
Rainer Wolff created an issue

After using the sort command on TObjectdataset, deletion of a record catches the wrong entry.

It seems that using fIndexes[k] instead of Items[k] in the sort algorithm fixes the problem. (see changes below)

procedure TIndexList.InsertionSort(startIndex: Integer;
  const comparer: TComparison);
var
  i, j : Integer;
  temp: TIndexItem;
begin
  startIndex := startIndex - 1;
  if startIndex < 0 then
    startIndex := 0;

  for i := startIndex + 1 to Count - 1 Do
  begin
    temp := fIndexes[i];
    j := i;
    while (j > 0) and (comparer(fIndexes[j - 1].Item, temp.Item) > 0) do
    begin
      fIndexes[j] := fIndexes[j - 1];
      Dec(j);
    end;
    fIndexes[j] := temp;
  end;
end;

procedure TIndexList.MergeSort(const comparer: TComparison);
var
  cache: TArray<TIndexItem>;

  procedure Merge(low, mid, high: Integer);
  var
    i, j, k: Integer;
  begin
    for i := low to high do
      cache[i] := fIndexes[i];
    i := low;
    j := mid + 1;
    k := low;
    while (i <= mid) and (j <= high) do
    begin
      if comparer(cache[i].Item, cache[j].item) <= 0 then
      begin
        fIndexes[k] := cache[i];
        Inc(i);
      end
      else
      begin
        fIndexes[k] := cache[j];
        Inc(j);
      end;
      Inc(k);
    end;

    while i <= mid do
    begin
      fIndexes[k] := cache[i];
      Inc(k);
      Inc(i);
    end;
  end;

  procedure PerformMergeSort(low, high: Integer);
  var
    mid: Integer;
  begin
    if low < high then
    begin
      mid := (high + low) div 2;
      PerformMergeSort(low, mid);
      PerformMergeSort(mid + 1, high);
      Merge(low, mid, high);
    end;
  end;

begin
  SetLength(cache, Count);
  PerformMergeSort(0, Count - 1);
end;

Comments (7)

  1. Stefan Glienke repo owner
    • changed status to open

    I am tempted to disable filtering and sorting of the dataset for this release (typically a grid component can do that anyway)

  2. Log in to comment