diff --git a/src/Compiler/AbstractIL/ilread.fs b/src/Compiler/AbstractIL/ilread.fs index 10189157adf..d872cc421e3 100644 --- a/src/Compiler/AbstractIL/ilread.fs +++ b/src/Compiler/AbstractIL/ilread.fs @@ -1201,9 +1201,12 @@ type ISeekReadIndexedRowReader<'RowT, 'KeyT, 'T when 'RowT: struct> = abstract CompareKey: 'KeyT -> int abstract ConvertRow: byref<'RowT> -> 'T -let seekReadIndexedRowsByInterface numRows binaryChop (reader: ISeekReadIndexedRowReader<'RowT, _, _>) = +let seekReadIndexedRowsRange numRows binaryChop (reader: ISeekReadIndexedRowReader<'RowT, _, _>) = let mutable row = Unchecked.defaultof<'RowT> + let mutable startRid = -1 + let mutable endRid = -1 + if binaryChop then let mutable low = 0 let mutable high = numRows + 1 @@ -1222,12 +1225,13 @@ let seekReadIndexedRowsByInterface numRows binaryChop (reader: ISeekReadIndexedR elif c < 0 then high <- mid else fin <- true - let res = ImmutableArray.CreateBuilder() - if high - low > 1 then // now read off rows, forward and backwards let mid = (low + high) / 2 + startRid <- mid + endRid <- mid + // read backwards let mutable fin = false let mutable curr = mid - 1 @@ -1239,17 +1243,15 @@ let seekReadIndexedRowsByInterface numRows binaryChop (reader: ISeekReadIndexedR reader.GetRow(curr, &row) if reader.CompareKey(reader.GetKey(&row)) = 0 then - res.Add(reader.ConvertRow(&row)) + startRid <- curr else fin <- true curr <- curr - 1 - res.Reverse() - // read forward let mutable fin = false - let mutable curr = mid + let mutable curr = mid + 1 while not fin do if curr > numRows then @@ -1258,23 +1260,49 @@ let seekReadIndexedRowsByInterface numRows binaryChop (reader: ISeekReadIndexedR reader.GetRow(curr, &row) if reader.CompareKey(reader.GetKey(&row)) = 0 then - res.Add(reader.ConvertRow(&row)) + endRid <- curr else fin <- true curr <- curr + 1 - res.ToArray() else - let res = ImmutableArray.CreateBuilder() + let mutable rid = 1 - for i = 1 to numRows do - reader.GetRow(i, &row) + while rid <= numRows && startRid = -1 do + reader.GetRow(rid, &row) if reader.CompareKey(reader.GetKey(&row)) = 0 then - res.Add(reader.ConvertRow(&row)) + startRid <- rid + endRid <- rid + + rid <- rid + 1 + + let mutable fin = false + + while rid <= numRows && not fin do + reader.GetRow(rid, &row) + + if reader.CompareKey(reader.GetKey(&row)) = 0 then + endRid <- rid + else + fin <- true + + rid <- rid + 1 + + startRid, endRid + +let seekReadIndexedRowsByInterface numRows binaryChop (reader: ISeekReadIndexedRowReader<'RowT, _, _>) = + let startRid, endRid = seekReadIndexedRowsRange numRows binaryChop reader + + if startRid <= 0 || endRid < startRid then + [||] + else - res.ToArray() + Array.init (endRid - startRid + 1) (fun i -> + let mutable row = Unchecked.defaultof<'RowT> + reader.GetRow(startRid + i, &row) + reader.ConvertRow(&row)) [] type CustomAttributeRow =