Repository navigation
Add internal block type for use in the compiler. IncrementalBuilder only maintains two states
#11750
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add internal block type for use in the compiler. IncrementalBuilder only maintains two states
#11750
Changes from 1 commit
bf5d851
27b1e6a
dce6baa
33b6493
a83952a
0a78706
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,14 +9,12 @@ type blockbuilder<'T> = ImmutableArray<'T>.Builder | |
| module BlockBuilder = | ||
|
|
||
| let create size : blockbuilder<'T> = | ||
| if size = 0 then | ||
| ImmutableArray.CreateBuilder() | ||
| else | ||
| ImmutableArray.CreateBuilder(size) | ||
| ImmutableArray.CreateBuilder(size) | ||
|
|
||
| [<RequireQualifiedAccess>] | ||
| module Block = | ||
|
|
||
| [<GeneralizableValue>] | ||
| let empty<'T> = ImmutableArray<'T>.Empty | ||
|
|
||
| let init n (f: int -> 'T) : block<_> = | ||
|
|
@@ -30,7 +28,7 @@ module Block = | |
| let builder = ImmutableArray.CreateBuilder(n) | ||
| for i = 0 to n - 1 do | ||
| builder.Add(f i) | ||
| builder.ToImmutable() | ||
| builder.MoveToImmutable() | ||
|
|
||
| let iter f (arr: block<'T>) = | ||
| for i = 0 to arr.Length - 1 do | ||
|
|
@@ -56,23 +54,23 @@ module Block = | |
|
|
||
| let map (mapper: 'T -> 'U) (arr: block<'T>) : block<_> = | ||
| match arr.Length with | ||
| | 0 -> block.Empty | ||
| | 0 -> ImmutableArray.Empty | ||
| | 1 -> ImmutableArray.Create(mapper arr.[0]) | ||
| | _ -> | ||
| let builder = ImmutableArray.CreateBuilder(arr.Length) | ||
| for i = 0 to arr.Length - 1 do | ||
| builder.Add(mapper arr.[i]) | ||
| builder.ToImmutable() | ||
| builder.MoveToImmutable() | ||
|
|
||
| let mapi (mapper: int -> 'T -> 'U) (arr: block<'T>) : block<_> = | ||
| match arr.Length with | ||
| | 0 -> block.Empty | ||
| | 0 -> ImmutableArray.Empty | ||
| | 1 -> ImmutableArray.Create(mapper 0 arr.[0]) | ||
| | _ -> | ||
| let builder = ImmutableArray.CreateBuilder(arr.Length) | ||
| for i = 0 to arr.Length - 1 do | ||
| builder.Add(mapper i arr.[i]) | ||
| builder.ToImmutable() | ||
| builder.MoveToImmutable() | ||
|
|
||
| let map2 (mapper: 'T1 -> 'T2 -> 'T) (arr1: block<'T1>) (arr2: block<'T2>) : block<_> = | ||
| if arr1.Length <> arr2.Length then | ||
|
|
@@ -85,7 +83,7 @@ module Block = | |
| let builder = ImmutableArray.CreateBuilder(n) | ||
| for i = 0 to n - 1 do | ||
| builder.Add(mapper arr1.[i] arr2.[i]) | ||
| builder.ToImmutable() | ||
| builder.MoveToImmutable() | ||
|
|
||
| let mapi2 (mapper: int -> 'T1 -> 'T2 -> 'T) (arr1: block<'T1>) (arr2: block<'T2>) : block<_> = | ||
| if arr1.Length <> arr2.Length then | ||
|
|
@@ -98,85 +96,55 @@ module Block = | |
| let builder = ImmutableArray.CreateBuilder(n) | ||
| for i = 0 to n - 1 do | ||
| builder.Add(mapper i arr1.[i] arr2.[i]) | ||
| builder.ToImmutable() | ||
|
|
||
| let concat (arr: block<block<'T>>) : block<'T> = | ||
| if arr.IsEmpty then | ||
| empty | ||
| elif arr.Length = 1 then | ||
| arr.[0] | ||
| elif arr.Length = 2 then | ||
| arr.[0].AddRange(arr.[1]) | ||
| else | ||
| let mutable arr2 = arr.[0] | ||
| for i = 1 to arr.Length - 1 do | ||
| arr2 <- arr2.AddRange(arr.[i]) | ||
| arr2 | ||
| builder.MoveToImmutable() | ||
|
|
||
| let concat (arrs: block<block<'T>>) : block<'T> = | ||
| match arrs.Length with | ||
| | 0 -> ImmutableArray.Empty | ||
| | 1 -> arrs.[0] | ||
| | 2 -> arrs.[0].AddRange(arrs.[1]) | ||
| | _ -> | ||
| let mutable acc = 0 | ||
| for h in arrs do | ||
| acc <- acc + h.Length | ||
|
|
||
| let builder = ImmutableArray.CreateBuilder(acc) | ||
| for i = 0 to arrs.Length - 1 do | ||
| builder.AddRange(arrs.[i]) | ||
| builder.MoveToImmutable() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing capacity <- count or ToImmutable here, as capacity could be anything.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is fine.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah I completely missed the the length summing loop, yep it's fine! |
||
|
|
||
| let forall predicate (arr: block<'T>) = | ||
|
TIHan marked this conversation as resolved.
Resolved
|
||
| match arr.Length with | ||
| | 0 -> true | ||
| | 1 -> predicate arr.[0] | ||
| | n -> | ||
| let mutable result = true | ||
| let mutable i = 0 | ||
| while result && i < n do | ||
| result <- predicate arr.[i] | ||
| i <- i + 1 | ||
| result | ||
| let len = arr.Length | ||
| let rec loop i = i >= len || (predicate arr.[i] && loop (i+1)) | ||
| loop 0 | ||
|
|
||
| let forall2 predicate (arr1: block<'T1>) (arr2: block<'T2>) = | ||
| if arr1.Length <> arr2.Length then | ||
| invalidOp "Block lengths do not match." | ||
|
|
||
| match arr1.Length with | ||
| | 0 -> true | ||
| | 1 -> predicate arr1.[0] arr2.[0] | ||
| | n -> | ||
| let mutable result = true | ||
| let mutable i = 0 | ||
| while result && i < n do | ||
| result <- predicate arr1.[i] arr2.[i] | ||
| i <- i + 1 | ||
| result | ||
| let f = OptimizedClosures.FSharpFunc<_, _, _>.Adapt(predicate) | ||
| let len1 = arr1.Length | ||
| let rec loop i = i >= len1 || (f.Invoke(arr1.[i], arr2.[i]) && loop (i+1)) | ||
| loop 0 | ||
|
|
||
| let tryFind predicate (arr: block<'T>) = | ||
| match arr.Length with | ||
| | 0 -> None | ||
| | 1 -> if predicate arr.[0] then Some arr.[0] else None | ||
| | n -> | ||
| let mutable result = None | ||
| let mutable i = 0 | ||
| while result.IsNone && i < n do | ||
| if predicate arr.[i] then | ||
| result <- Some arr.[i] | ||
| i <- i + 1 | ||
| result | ||
| let rec loop i = | ||
| if i >= arr.Length then None else | ||
| if predicate arr.[i] then Some arr.[i] else loop (i+1) | ||
| loop 0 | ||
|
|
||
| let tryFindIndex predicate (arr: block<'T>) = | ||
| match arr.Length with | ||
| | 0 -> None | ||
| | 1 -> if predicate arr.[0] then Some 0 else None | ||
| | n -> | ||
| let mutable result = None | ||
| let mutable i = 0 | ||
| while result.IsNone && i < n do | ||
| if predicate arr.[i] then | ||
| result <- Some i | ||
| i <- i + 1 | ||
| result | ||
| let len = arr.Length | ||
| let rec go n = if n >= len then None elif predicate arr.[n] then Some n else go (n+1) | ||
| go 0 | ||
|
|
||
| let tryPick chooser (arr: block<'T>) = | ||
| match arr.Length with | ||
| | 0 -> None | ||
| | 1 -> chooser arr.[0] | ||
| | n -> | ||
| let mutable result = None | ||
| let mutable i = 0 | ||
| while result.IsNone && i < n do | ||
| result <- chooser arr.[i] | ||
| i <- i + 1 | ||
| result | ||
| let rec loop i = | ||
| if i >= arr.Length then None else | ||
| match chooser arr.[i] with | ||
| | None -> loop(i+1) | ||
| | res -> res | ||
| loop 0 | ||
|
|
||
| let ofSeq (xs: 'T seq) = | ||
| ImmutableArray.CreateRange(xs) | ||
|
|
@@ -192,25 +160,22 @@ module Block = | |
| for i = 0 to arr.Length - 1 do | ||
| if predicate arr.[i] then | ||
| builder.Add(arr.[i]) | ||
| builder.ToImmutable() | ||
| builder.Capacity <- builder.Count | ||
| builder.MoveToImmutable() | ||
|
|
||
| let exists predicate (arr: block<'T>) = | ||
| let n = arr.Length | ||
| let mutable result = false | ||
| let mutable i = 0 | ||
| while not result && i < n do | ||
| if predicate arr.[i] then | ||
| result <- true | ||
| i <- i + 1 | ||
| result | ||
| let len = arr.Length | ||
| let rec loop i = i < len && (predicate arr.[i] || loop (i+1)) | ||
| len > 0 && loop 0 | ||
|
|
||
| let choose (chooser: 'T -> 'U option) (arr: block<'T>) : block<'U> = | ||
| let builder = ImmutableArray.CreateBuilder(arr.Length) | ||
| for i = 0 to arr.Length - 1 do | ||
| let result = chooser arr.[i] | ||
| if result.IsSome then | ||
| builder.Add(result.Value) | ||
| builder.ToImmutable() | ||
| builder.Capacity <- builder.Count | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you don't know the length it doesn't matter too much if you do ToImmutable. You'll do a copy by changing capacity anyway.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changing the capacity will only copy if the count is different.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair enough :) |
||
| builder.MoveToImmutable() | ||
|
|
||
| let isEmpty (arr: block<_>) = arr.Length = 0 | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.