Skip to content

Commit 30d5298

Browse files
committed
* added adaptive tools for FileSystem queries (AdaptiveFile/AdaptiveDirectory)
* `IndexList.computeDeltaToArrayAndGetResult` * `HashSetDelta.ChooseV`
1 parent c16b071 commit 30d5298

13 files changed

Lines changed: 786 additions & 6 deletions

File tree

FSharp.Data.Adaptive.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpInterop", "src\Demo\C
2020
EndProject
2121
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{3F9BDA4B-D949-46D6-B237-07FE80CBBB53}"
2222
EndProject
23+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FileSystem", "src\Demo\FileSystem\FileSystem.fsproj", "{2AE99C0D-703D-4042-9E8D-BF8A66284B0D}"
24+
EndProject
2325
Global
2426
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2527
Debug|Any CPU = Debug|Any CPU
@@ -54,6 +56,10 @@ Global
5456
{D4058F6D-A8D5-4587-AE05-D32A3B99B625}.Debug|Any CPU.Build.0 = Debug|Any CPU
5557
{D4058F6D-A8D5-4587-AE05-D32A3B99B625}.Release|Any CPU.ActiveCfg = Release|Any CPU
5658
{D4058F6D-A8D5-4587-AE05-D32A3B99B625}.Release|Any CPU.Build.0 = Release|Any CPU
59+
{2AE99C0D-703D-4042-9E8D-BF8A66284B0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
60+
{2AE99C0D-703D-4042-9E8D-BF8A66284B0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
61+
{2AE99C0D-703D-4042-9E8D-BF8A66284B0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
62+
{2AE99C0D-703D-4042-9E8D-BF8A66284B0D}.Release|Any CPU.Build.0 = Release|Any CPU
5763
EndGlobalSection
5864
GlobalSection(SolutionProperties) = preSolution
5965
HideSolutionNode = FALSE
@@ -64,6 +70,7 @@ Global
6470
{03B1322E-F6C8-4CF2-84DD-8996A2373479} = {B5A29D79-4C76-4148-A69F-814ED1BEEFCE}
6571
{B978F3DF-9F10-493E-97E9-0248491D41D9} = {B5A29D79-4C76-4148-A69F-814ED1BEEFCE}
6672
{D4058F6D-A8D5-4587-AE05-D32A3B99B625} = {B5A29D79-4C76-4148-A69F-814ED1BEEFCE}
73+
{2AE99C0D-703D-4042-9E8D-BF8A66284B0D} = {B5A29D79-4C76-4148-A69F-814ED1BEEFCE}
6774
EndGlobalSection
6875
GlobalSection(ExtensibilityGlobals) = postSolution
6976
SolutionGuid = {0E91AEEA-75F2-484D-8E5E-E3322D13C65A}

RELEASE_NOTES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
### 1.2.5
2+
* fixed GC problem with `AVal.mapNonAdaptive`
3+
* added adaptive FileSystem tools
4+
* implemented efficient `IndexList.computeDeltaTo(Array|List|Seq)` (https://neil.fraser.name/writing/diff/myers.pdf)
5+
16
### 1.2.4
27
* raised minimal FSharp.Core version to 4.7.0 (necessary due to Fable.Core update)
38

build.fsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ Target.create "NpmInstall" (fun _ ->
179179
)
180180

181181
Target.create "CompileFable" (fun _ ->
182-
DotNet.exec (fun o -> o) "fable" "src/Demo/Fable/Fable.fsproj"
182+
DotNet.exec (fun o -> o) "fable" "src/Demo/Fable/Fable.fsproj -o bin/Fable"
183183
|> ignore
184184
//CreateProcess.fromRawCommand "node" [npx; "fable-splitter"; "-c"; "splitter-config.js"]
185185
//|> CreateProcess.withWorkingDirectory Environment.CurrentDirectory
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project Sdk="Microsoft.NET.Sdk">
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp3.1</TargetFramework>
6+
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
7+
</PropertyGroup>
8+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
9+
<OutputPath>..\..\..\bin\Release\</OutputPath>
10+
</PropertyGroup>
11+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
12+
<OutputPath>..\..\..\bin\Debug\</OutputPath>
13+
</PropertyGroup>
14+
<ItemGroup>
15+
<Compile Include="PrettyPrint.fs" />
16+
<Compile Include="Program.fs" />
17+
</ItemGroup>
18+
<ItemGroup>
19+
<ProjectReference Include="..\..\FSharp.Data.Adaptive\FSharp.Data.Adaptive.fsproj" />
20+
</ItemGroup>
21+
<Import Project="..\..\..\.paket\Paket.Restore.targets" />
22+
</Project>

src/Demo/FileSystem/PrettyPrint.fs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
module Pretty
2+
3+
open System
4+
open FSharp.Data.Adaptive
5+
6+
let cprintfn color fmt =
7+
fmt |> Printf.kprintf (fun str ->
8+
let o = Console.ForegroundColor
9+
try
10+
Console.ForegroundColor <- color
11+
Console.WriteLine("{0}", str)
12+
finally
13+
Console.ForegroundColor <- o
14+
15+
)
16+
17+
let rec print (pos : int) (a : list<Index * string>) (b : list<Index * ElementOperation<string>>) =
18+
match a with
19+
| (iha, vha) :: ta ->
20+
match b with
21+
| (ihb, vhb) :: tb ->
22+
if iha < ihb then
23+
printfn " %3d: %s" pos vha
24+
print (pos + 1) ta b
25+
elif iha > ihb then
26+
match vhb with
27+
| Set v ->
28+
cprintfn ConsoleColor.Green " + %s" v
29+
| Remove ->
30+
() // BAD
31+
print (pos + 1) a tb
32+
else
33+
match vhb with
34+
| Set v ->
35+
cprintfn ConsoleColor.Red " - %s" vha
36+
cprintfn ConsoleColor.Green " + %s" v
37+
print (pos + 1) ta tb
38+
| Remove ->
39+
cprintfn ConsoleColor.Red " - %s" vha
40+
print pos ta tb
41+
| [] ->
42+
printfn " %3d: %s" pos vha
43+
print (pos + 1) ta b
44+
| [] ->
45+
match b with
46+
| (ihb, vhb) :: tb ->
47+
match vhb with
48+
| Set v ->
49+
cprintfn ConsoleColor.Green " + %s" v
50+
| Remove ->
51+
()
52+
print (pos + 1) a tb
53+
| [] ->
54+
()
55+

src/Demo/FileSystem/Program.fs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
open System
2+
open System.IO
3+
open FSharp.Data.Adaptive
4+
open System.Threading
5+
6+
// This example uses AdaptiveDirectory and AdaptiveFile to read all lines
7+
// from all files in a directory maintaining a single adaptive list of lines.
8+
9+
[<EntryPoint>]
10+
let main _argv =
11+
12+
// create a temporary directory
13+
let dir = Path.Combine(Path.GetTempPath(), Guid.NewGuid() |> string)
14+
Directory.CreateDirectory dir |> ignore
15+
16+
// get the lines of all files (sorted by name) concatenated in one alist.
17+
let content =
18+
AdaptiveDirectory.GetFiles(dir, true)
19+
|> ASet.sortBy (fun info -> info.Name)
20+
|> AList.collect (fun info ->
21+
AdaptiveFile.ReadAllLinesAList info.FullName
22+
)
23+
24+
// for demonstration purposes we want to wait until the
25+
// callback gets executed after each change, therefore
26+
// we use a Semaphore here.
27+
let callbackSem = new SemaphoreSlim(0)
28+
29+
// subscribe to changes and pretty-print the changes.
30+
let subscription =
31+
content.AddCallback (fun oldState delta ->
32+
// print the change
33+
Pretty.print 1 (IndexList.toListIndexed oldState) (IndexListDelta.toList delta)
34+
printfn ""
35+
36+
// tell the main-thread we're done printing
37+
callbackSem.Release() |> ignore
38+
)
39+
40+
// some temporary files
41+
let a = Path.Combine(dir, "a.txt")
42+
let b = Path.Combine(dir, "b.txt")
43+
let c = Path.Combine(dir, "c.txt")
44+
let d = Path.Combine(dir, "d.txt")
45+
46+
// perform some changes and wait for our print
47+
printfn "write a.txt"
48+
File.WriteAllText(a, "This is file a")
49+
callbackSem.Wait()
50+
51+
printfn "write c.txt"
52+
File.WriteAllText(c, "File c has\r\ntwo lines")
53+
callbackSem.Wait()
54+
55+
printfn "write b.txt"
56+
File.WriteAllText(b, "b also exists now!")
57+
callbackSem.Wait()
58+
59+
printfn "update b.txt"
60+
File.WriteAllText(b, "b has a new line!\r\nb also exists now!\r\nand another one")
61+
callbackSem.Wait()
62+
63+
printfn "delete a.txt"
64+
File.Delete a
65+
callbackSem.Wait()
66+
67+
printfn "write a.txt"
68+
File.WriteAllText(a, "THIS\r\nIS FILE A")
69+
callbackSem.Wait()
70+
71+
printfn "b.txt -> d.txt"
72+
File.Move(b, d)
73+
callbackSem.Wait()
74+
75+
76+
// dispose our subscription and delete the temp-directory
77+
subscription.Dispose()
78+
Directory.Delete(dir, true)
79+
80+
81+
0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
FSharp.Core

src/FSharp.Data.Adaptive/AdaptiveIndexList/AdaptiveIndexList.fs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,10 +1090,16 @@ module internal AdaptiveIndexListImplementation =
10901090
let mutable last = IndexList.empty
10911091

10921092
override x.Compute(token: AdaptiveToken) =
1093-
let v = input.GetValue token |> IndexList.ofSeq
1094-
let ops = IndexList.computeDelta last v
1095-
last <- v
1096-
ops
1093+
let v = input.GetValue token
1094+
match v :> seq<_> with
1095+
| :? IndexList<'a> as v ->
1096+
let ops = IndexList.computeDelta last v
1097+
last <- v
1098+
ops
1099+
| _ ->
1100+
let ops, n = IndexList.computeDeltaToArrayAndGetResult DefaultEqualityComparer.Instance last (Seq.toArray v)
1101+
last <- n
1102+
ops
10971103

10981104
/// Reader for pairwise operations
10991105
[<Sealed>]

0 commit comments

Comments
 (0)