-
Notifications
You must be signed in to change notification settings - Fork 45
/
Collector.fs
78 lines (61 loc) · 2.46 KB
/
Collector.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
namespace Nessos.LinqOptimizer.Core
open System
open System.Collections
open System.Collections.Generic
open System.Linq
open System.Linq.Expressions
open System.Reflection
open System.Collections.Concurrent
type ArrayCollector<'T> () =
let ls = List<'T [] * int>()
let mutable isAdd = false
let bufferSize = 1024
let mutable currentBufferSize = bufferSize
let newBuffer( size ) = currentBufferSize <- size; Array.zeroCreate<'T> size
let mutable buffer : 'T [] = newBuffer bufferSize
let mutable idx = 0
let flushBuffer () =
ls.Add(buffer, idx)
buffer <- newBuffer bufferSize
isAdd <- false
idx <- 0
member this.AddRange(collector : ArrayCollector<'T>) =
this.Flush()
collector.Flush()
Seq.iter ls.Add collector.ArrayList
member this.Add(elem : 'T) =
isAdd <- true
if idx >= currentBufferSize then
let newBuf = newBuffer (currentBufferSize * 2)
Array.Copy(buffer, newBuf, idx)
buffer <- newBuf
this.Add(elem)
else
buffer.[idx] <- elem
idx <- idx + 1
member this.ToArray () : 'T [] =
this.Flush()
let mutable length = 0
for (_, l) in ls do
length <- length + l
let final = Array.zeroCreate length
let mutable currIdx = 0
for (array, l) in ls do
Array.Copy(array, 0, final, currIdx, l)
currIdx <- currIdx + l
final
member this.ToList () : List<'T> =
List<'T>(this.ToArray())
member internal this.ArrayList with get () = ls
member internal this.Flush () =
if isAdd then flushBuffer ()
interface IEnumerable<'T> with
member this.GetEnumerator() =
let array = this.ToArray() :> IEnumerable<'T>
array.GetEnumerator()
member this.GetEnumerator() =
let list = this.ToArray()
list.GetEnumerator()
interface IOrderedEnumerable<'T> with
member __.CreateOrderedEnumerable<'TKey>(keySelector : Func<'T, 'TKey> , comparer : IComparer<'TKey>, desc : bool) =
raise <| NotImplementedException()