FileSystem (Polyglot)¶
In [ ]:
#r @"../../../../../../../.nuget/packages/fsharp.control.asyncseq/3.2.1/lib/netstandard2.1/FSharp.Control.AsyncSeq.dll"
#r @"../../../../../../../.nuget/packages/system.reactive/6.0.1-preview.1/lib/net6.0/System.Reactive.dll"
#r @"../../../../../../../.nuget/packages/system.reactive.linq/6.0.1-preview.1/lib/netstandard2.0/System.Reactive.Linq.dll"
#r @"../../../../../../../.nuget/packages/argu/6.2.4/lib/netstandard2.0/Argu.dll"
In [ ]:
#!import ../../lib/fsharp/Notebooks.dib
#!import ../../lib/fsharp/Testing.dib
In [ ]:
#!import ../../lib/fsharp/Common.fs
#!import ../../lib/fsharp/CommonFSharp.fs
#!import ../../lib/fsharp/Async.fs
#!import ../../lib/fsharp/AsyncSeq.fs
#!import ../../lib/fsharp/Runtime.fs
In [ ]:
#if !INTERACTIVE
open Lib
#endif
In [ ]:
open Common
open SpiralFileSystem.Operators
watchDirectory¶
In [ ]:
[<RequireQualifiedAccess>]
type FileSystemChangeType =
| Failure
| Changed
| Created
| Deleted
| Renamed
[<RequireQualifiedAccess>]
type FileSystemChange =
| Failure of exn: exn
| Changed of path: string * content: string option
| Created of path: string * content: string option
| Deleted of path: string
| Renamed of oldPath: string * (string * string option)
let inline watchDirectoryWithFilter filter shouldReadContent path =
let fullPath = path |> System.IO.Path.GetFullPath
let _locals () = $"filter: {filter} / {_locals ()}"
let watcher =
new System.IO.FileSystemWatcher (
Path = fullPath,
NotifyFilter = filter,
EnableRaisingEvents = true,
IncludeSubdirectories = true
)
let inline getEventPath (path : string) =
path |> SpiralSm.trim |> SpiralSm.replace fullPath "" |> SpiralSm.trim_start [| '/'; '\\' |]
let inline ticks () =
System.DateTime.UtcNow.Ticks
let changedStream =
AsyncSeq.subscribeEvent
watcher.Changed
(fun event ->
ticks (),
[ FileSystemChange.Changed (getEventPath event.FullPath, None) ]
)
let deletedStream =
AsyncSeq.subscribeEvent
watcher.Deleted
(fun event ->
ticks (),
[ FileSystemChange.Deleted (getEventPath event.FullPath) ]
)
let createdStream =
AsyncSeq.subscribeEvent
watcher.Created
(fun event ->
let path = getEventPath event.FullPath
ticks (), [
FileSystemChange.Created (path, None)
if SpiralPlatform.is_windows () then
FileSystemChange.Changed (path, None)
])
let renamedStream =
AsyncSeq.subscribeEvent
watcher.Renamed
(fun event ->
ticks (), [
FileSystemChange.Renamed (
getEventPath event.OldFullPath,
(getEventPath event.FullPath, None)
)
]
)
let failureStream =
AsyncSeq.subscribeEvent
watcher.Error
(fun event -> ticks (), [ FileSystemChange.Failure (event.GetException ()) ])
let stream =
[
changedStream
deletedStream
createdStream
renamedStream
failureStream
]
|> FSharp.Control.AsyncSeq.mergeAll
|> FSharp.Control.AsyncSeq.map (fun (t, events) ->
events
|> List.fold
(fun (i, events) event ->
i + 1L,
(t + i, event) :: events)
(0L, [])
|> snd
|> List.rev
)
|> FSharp.Control.AsyncSeq.concatSeq
|> FSharp.Control.AsyncSeq.mapAsyncParallel (fun (t, event) -> async {
match shouldReadContent event, event with
| true, FileSystemChange.Changed (path, _) ->
do! Async.Sleep 5
let! content = fullPath </> path |> SpiralFileSystem.read_all_text_retry_async
return t, FileSystemChange.Changed (path, content)
| true, FileSystemChange.Created (path, _) ->
do! Async.Sleep 5
let! content = fullPath </> path |> SpiralFileSystem.read_all_text_retry_async
return t, FileSystemChange.Created (path, content)
| true, FileSystemChange.Renamed (oldPath, (newPath, _)) ->
let! content = fullPath </> newPath |> SpiralFileSystem.read_all_text_retry_async
return t, FileSystemChange.Renamed (oldPath, (newPath, content))
| _ -> return t, event
})
let disposable =
new_disposable (fun () ->
trace Debug (fun () -> "FileSystem.watchWithFilter / Disposing watch stream") _locals
watcher.EnableRaisingEvents <- false
watcher.Dispose ()
)
stream, disposable
let inline watchDirectory path =
watchDirectoryWithFilter
(System.IO.NotifyFilters.FileName
// ||| System.IO.NotifyFilters.DirectoryName
// ||| System.IO.NotifyFilters.Attributes
//// ||| System.IO.NotifyFilters.Size
||| System.IO.NotifyFilters.LastWrite
//// ||| System.IO.NotifyFilters.LastAccess
// ||| System.IO.NotifyFilters.CreationTime
// ||| System.IO.NotifyFilters.Security
)
path
testEventsRaw (test)¶
In [ ]:
//// test
let inline testEventsRaw
(watchFn : (_ -> bool) -> string -> FSharp.Control.AsyncSeq<int64 * FileSystemChange> * IDisposable)
write
=
let struct (tempDir, tempDisposable) =
"FileSystem.testEventsRaw"
|> SpiralCrypto.hash_text
|> SpiralFileSystem.create_temp_dir'
let stream, disposable = watchFn (fun _ -> true) tempDir
let events = System.Collections.Concurrent.ConcurrentBag ()
let inline iter () =
stream
|> FSharp.Control.AsyncSeq.iterAsyncParallel (fun event -> async { events.Add event })
let run = async {
let! _ = iter () |> Async.StartChild
do! Async.Sleep 250
return! write tempDir
}
try
run
|> Async.runWithTimeout 60000
|> _assertEqual (Some ())
finally
disposable.Dispose ()
tempDisposable.Dispose ()
let eventsLog =
events
|> Seq.toList
|> List.sortBy fst
|> List.fold
(fun (prev, acc) (ticks, event) ->
ticks, (ticks, (if prev = 0L then 0L else ticks - prev), event) :: acc
)
(0L, [])
|> snd
|> List.rev
|> List.map (fun (diff, n, event) -> $"{n} / {diff} / {event}" |> SpiralSm.ellipsis_end 100L)
|> SpiralSm.concat "\n"
let _locals () = $"eventsLog: \n{eventsLog} / {_locals ()}"
trace Debug (fun () -> "FileSystem.testEventsRaw") _locals
events
|> Seq.toList
|> List.sortBy fst
|> List.map snd
|> List.fold
(fun acc event ->
match acc, event with
| FileSystemChange.Changed (lastPath, Some lastContent) as lastEvent :: acc,
FileSystemChange.Changed (path, Some content)
when lastPath = path && content |> SpiralSm.starts_with lastContent
->
event :: acc
| _ -> event :: acc
)
[]
|> List.rev
fast (test)¶
In [ ]:
//// test
let inline write path = async {
let n = 2
for i = 1 to n do
do! $"a{i}" |> SpiralFileSystem.write_all_text_async (path </> $"file{i}.txt")
do! Async.Sleep 250
for i = 1 to n do
do! $"b{i}" |> SpiralFileSystem.write_all_text_async (path </> $"file{i}.txt")
do! Async.Sleep 250
for i = 1 to n do
do! path </> $"file{i}.txt" |> SpiralFileSystem.move_file_async (path </> $"file_{i}.txt") |> Async.Ignore
do! Async.Sleep 250
for i = 1 to n do
do! $"c{i}" |> SpiralFileSystem.write_all_text_async (path </> $"file_{i}.txt")
do! Async.Sleep 250
for i = 1 to n do
do! SpiralFileSystem.delete_file_async (path </> $"file_{i}.txt") |> Async.Ignore
do! Async.Sleep 250
}
let inline run () =
let events = testEventsRaw watchDirectory write
events
|> _sequenceEqual [
FileSystemChange.Created ("file1.txt", Some "a1")
FileSystemChange.Changed ("file1.txt", Some "a1")
FileSystemChange.Created ("file2.txt", Some "a2")
FileSystemChange.Changed ("file2.txt", Some "a2")
FileSystemChange.Changed ("file1.txt", Some "b1")
FileSystemChange.Changed ("file2.txt", Some "b2")
FileSystemChange.Renamed ("file1.txt", ("file_1.txt", Some "b1"))
FileSystemChange.Renamed ("file2.txt", ("file_2.txt", Some "b2"))
FileSystemChange.Changed ("file_1.txt", Some "c1")
FileSystemChange.Changed ("file_2.txt", Some "c2")
FileSystemChange.Deleted "file_1.txt"
FileSystemChange.Deleted "file_2.txt"
]
run
|> retry_fn 3
|> _assertEqual (Some ())
Some () 00:00:04 d #1 FileSystem.watchWithFilter / Disposing watch stream / filter: FileName, LastWrite 00:00:04 d #2 FileSystem.testEventsRaw / eventsLog: 0 / 638737681003551273 / Created ("file1.txt", Some "a1") 11924 / 638737681003563197 / Changed ("file1.txt", Some "a1") 1360 / 638737681003564557 / Created ("file2.txt", Some "a2") 34 / 638737681003564591 / Changed ("file2.txt", Some "a2") 2485623 / 638737681006050214 / Changed ("file1.txt", Some "b1") 470 / 638737681006050684 / Changed ("file1.txt", Some "b1") 5333 / 638737681006056017 / Changed ("file2.txt", Some "b2") 204 / 638737681006056221 / Changed ("file2.txt", Some "b2") 2558522 / 638737681008614743 / Renamed ("file1.txt", ("file_1.txt", Some "b1")) 7139 / 638737681008621882 / Renamed ("file2.txt", ("file_2.txt", Some "b2")) 2523127 / 638737681011145009 / Changed ("file_1.txt", Some "c1") 537 / 638737681011145546 / Changed ("file_1.txt", Some "c1") 5228 / 638737681011150774 / Changed ("file_2.txt", Some "c2") 293 / 638737681011151067 / Changed ("file_2.txt", Some "c2") 2532926 / 638737681013683993 / Deleted "file_1.txt" 1028 / 638737681013685021 / Deleted "file_2.txt" [Created ("file1.txt", Some "a1"); Changed ("file1.txt", Some "a1"); Created ("file2.txt", Some "a2"); Changed ("file2.txt", Some "a2"); Changed ("file1.txt", Some "b1"); Changed ("file2.txt", Some "b2"); Renamed ("file1.txt", ("file_1.txt", Some "b1")); Renamed ("file2.txt", ("file_2.txt", Some "b2")); Changed ("file_1.txt", Some "c1"); Changed ("file_2.txt", Some "c2"); Deleted "file_1.txt"; Deleted "file_2.txt"] Some ()
slow (test)¶
In [ ]:
//// test
let inline write path = async {
let n = 2
let contents =
[ 1 .. n ]
|> List.map (string >> String.replicate 1_000_000)
for i = 1 to n do
do! $"{contents.[i - 1]}a" |> SpiralFileSystem.write_all_text_async (path </> $"file{i}.txt")
do! Async.Sleep 1500
for i = 1 to n do
do! $"{contents.[i - 1]}b" |> SpiralFileSystem.write_all_text_async (path </> $"file{i}.txt")
do! Async.Sleep 1500
for i = 1 to n do
do! path </> $"file{i}.txt" |> SpiralFileSystem.move_file_async (path </> $"file_{i}.txt") |> Async.Ignore
do! Async.Sleep 1500
for i = 1 to n do
do! $"{contents.[i - 1]}c" |> SpiralFileSystem.write_all_text_async (path </> $"file_{i}.txt")
do! Async.Sleep 1500
for i = 1 to n do
do! SpiralFileSystem.delete_file_async (path </> $"file_{i}.txt") |> Async.Ignore
do! Async.Sleep 1500
}
let inline run () =
let events =
testEventsRaw watchDirectory write
|> List.map (function
| FileSystemChange.Changed (path, Some content) ->
FileSystemChange.Changed (path, content |> Seq.distinct |> Seq.map string |> SpiralSm.concat "" |> Some)
| FileSystemChange.Created (path, Some content) ->
FileSystemChange.Created (path, content |> Seq.distinct |> Seq.map string |> SpiralSm.concat "" |> Some)
| FileSystemChange.Renamed (oldPath, (newPath, Some content)) ->
FileSystemChange.Renamed (
oldPath,
(newPath, content |> Seq.distinct |> Seq.map string |> SpiralSm.concat "" |> Some)
)
| event -> event
)
events
|> _sequenceEqual [
FileSystemChange.Created ("file1.txt", Some "1a")
FileSystemChange.Changed ("file1.txt", Some "1a")
FileSystemChange.Created ("file2.txt", Some "2a")
FileSystemChange.Changed ("file2.txt", Some "2a")
FileSystemChange.Changed ("file1.txt", Some "1b")
FileSystemChange.Changed ("file2.txt", Some "2b")
FileSystemChange.Renamed ("file1.txt", ("file_1.txt", Some "1b"))
FileSystemChange.Renamed ("file2.txt", ("file_2.txt", Some "2b"))
FileSystemChange.Changed ("file_1.txt", Some "1c")
FileSystemChange.Changed ("file_2.txt", Some "2c")
FileSystemChange.Deleted "file_1.txt"
FileSystemChange.Deleted "file_2.txt"
]
run
|> retry_fn 5
|> _assertEqual (Some ())
Some () 00:00:12 d #3 FileSystem.watchWithFilter / Disposing watch stream / filter: FileName, LastWrite 00:00:14 d #4 FileSystem.testEventsRaw / eventsLog: 0 / 638737681029586398 / Created ("file1.txt", ...11111111111111111111111111111111111111111111111a") 3482 / 638737681029589880 / Changed ("file1.txt"...11111111111111111111111111111111111111111111111a") 219 / 638737681029590099 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 49 / 638737681029590148 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 1818 / 638737681029591966 / Changed ("file1.txt"...11111111111111111111111111111111111111111111111a") 161 / 638737681029592127 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 79 / 638737681029592206 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 67 / 638737681029592273 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 260 / 638737681029592533 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 68 / 638737681029592601 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 45 / 638737681029592646 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 247 / 638737681029592893 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 111 / 638737681029593004 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 208 / 638737681029593212 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 176 / 638737681029593388 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 73 / 638737681029593461 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 146 / 638737681029593607 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 118 / 638737681029593725 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 95 / 638737681029593820 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 61 / 638737681029593881 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 176 / 638737681029594057 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 170 / 638737681029594227 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 53 / 638737681029594280 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 409 / 638737681029594689 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 54 / 638737681029594743 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 38 / 638737681029594781 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 195 / 638737681029594976 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 43 / 638737681029595019 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 201 / 638737681029595220 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 133 / 638737681029595353 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 54 / 638737681029595407 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 167 / 638737681029595574 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 41 / 638737681029595615 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 159 / 638737681029595774 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 135 / 638737681029595909 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 44 / 638737681029595953 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 201 / 638737681029596154 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 52 / 638737681029596206 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 172 / 638737681029596378 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 39 / 638737681029596417 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 168 / 638737681029596585 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 43 / 638737681029596628 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 194 / 638737681029596822 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 138 / 638737681029596960 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 41 / 638737681029597001 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 209 / 638737681029597210 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 40 / 638737681029597250 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 948 / 638737681029598198 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 144 / 638737681029598342 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 51 / 638737681029598393 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 233 / 638737681029598626 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 54 / 638737681029598680 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 70 / 638737681029598750 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 326 / 638737681029599076 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 56 / 638737681029599132 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 12242 / 638737681029611374 / Created ("file2.txt...22222222222222222222222222222222222222222222222a") 195 / 638737681029611569 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 544 / 638737681029612113 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 458 / 638737681029612571 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 68 / 638737681029612639 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 66 / 638737681029612705 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 1079 / 638737681029613784 / Changed ("file2.txt"...22222222222222222222222222222222222222222222222a") 86 / 638737681029613870 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 47 / 638737681029613917 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 235 / 638737681029614152 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 57 / 638737681029614209 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 166 / 638737681029614375 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 165 / 638737681029614540 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 66 / 638737681029614606 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 208 / 638737681029614814 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 56 / 638737681029614870 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 155 / 638737681029615025 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 49 / 638737681029615074 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 229 / 638737681029615303 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 57 / 638737681029615360 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 190 / 638737681029615550 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 50 / 638737681029615600 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 250 / 638737681029615850 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 59 / 638737681029615909 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 156 / 638737681029616065 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 131 / 638737681029616196 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 196 / 638737681029616392 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 72 / 638737681029616464 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 213 / 638737681029616677 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 57 / 638737681029616734 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 172 / 638737681029616906 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 265 / 638737681029617171 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 55 / 638737681029617226 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 2395 / 638737681029619621 / Changed ("file2.txt"...22222222222222222222222222222222222222222222222a") 113 / 638737681029619734 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 228 / 638737681029619962 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 53 / 638737681029620015 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 235 / 638737681029620250 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 178 / 638737681029620428 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 1672 / 638737681029622100 / Changed ("file2.txt"...22222222222222222222222222222222222222222222222a") 95 / 638737681029622195 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 247 / 638737681029622442 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 246 / 638737681029622688 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 58 / 638737681029622746 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 1417 / 638737681029624163 / Changed ("file2.txt"...22222222222222222222222222222222222222222222222a") 66 / 638737681029624229 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 3020 / 638737681029627249 / Changed ("file2.txt"...22222222222222222222222222222222222222222222222a") 15048673 / 638737681044675922 / Changed ("file1....11111111111111111111111111111111111111111111111b") 393 / 638737681044676315 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 440 / 638737681044676755 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 290 / 638737681044677045 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 40 / 638737681044677085 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 49 / 638737681044677134 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 2494 / 638737681044679628 / Changed ("file1.txt"...11111111111111111111111111111111111111111111111b") 136 / 638737681044679764 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 246 / 638737681044680010 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 399 / 638737681044680409 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 458 / 638737681044680867 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 69 / 638737681044680936 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 266 / 638737681044681202 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 168 / 638737681044681370 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 175 / 638737681044681545 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 159 / 638737681044681704 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 179 / 638737681044681883 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 154 / 638737681044682037 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 151 / 638737681044682188 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 155 / 638737681044682343 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 165 / 638737681044682508 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 170 / 638737681044682678 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 156 / 638737681044682834 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 61 / 638737681044682895 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 302 / 638737681044683197 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 48 / 638737681044683245 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 279 / 638737681044683524 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 332 / 638737681044683856 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 51 / 638737681044683907 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 261 / 638737681044684168 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 53 / 638737681044684221 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 57 / 638737681044684278 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 266 / 638737681044684544 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 184 / 638737681044684728 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 44 / 638737681044684772 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 216 / 638737681044684988 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 187 / 638737681044685175 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 47 / 638737681044685222 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 219 / 638737681044685441 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 40 / 638737681044685481 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 198 / 638737681044685679 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 192 / 638737681044685871 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 45 / 638737681044685916 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 241 / 638737681044686157 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 43 / 638737681044686200 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 226 / 638737681044686426 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 54 / 638737681044686480 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 37 / 638737681044686517 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 780 / 638737681044687297 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 56 / 638737681044687353 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 35 / 638737681044687388 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 265 / 638737681044687653 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 159 / 638737681044687812 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 361 / 638737681044688173 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 259 / 638737681044688432 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 161 / 638737681044688593 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 165 / 638737681044688758 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 153 / 638737681044688911 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 169 / 638737681044689080 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 152 / 638737681044689232 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 159 / 638737681044689391 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 128 / 638737681044689519 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 185 / 638737681044689704 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 47 / 638737681044689751 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 751 / 638737681044690502 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 66 / 638737681044690568 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 39 / 638737681044690607 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 208 / 638737681044690815 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 46 / 638737681044690861 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 178 / 638737681044691039 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 553 / 638737681044691592 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 55 / 638737681044691647 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 40 / 638737681044691687 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 197 / 638737681044691884 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 47 / 638737681044691931 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 179 / 638737681044692110 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 160 / 638737681044692270 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 168 / 638737681044692438 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 214 / 638737681044692652 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 192 / 638737681044692844 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 45 / 638737681044692889 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 208 / 638737681044693097 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 657 / 638737681044693754 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 17613 / 638737681044711367 / Changed ("file2.txt...22222222222222222222222222222222222222222222222b") 119 / 638737681044711486 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 308 / 638737681044711794 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 192 / 638737681044711986 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 184 / 638737681044712170 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 223 / 638737681044712393 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 50 / 638737681044712443 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 165 / 638737681044712608 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 45 / 638737681044712653 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 148 / 638737681044712801 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 113 / 638737681044712914 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 167 / 638737681044713081 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 314 / 638737681044713395 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 210 / 638737681044713605 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 49 / 638737681044713654 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 207 / 638737681044713861 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 191 / 638737681044714052 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 186 / 638737681044714238 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 43 / 638737681044714281 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 775 / 638737681044715056 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 42 / 638737681044715098 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 45 / 638737681044715143 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 196 / 638737681044715339 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 46 / 638737681044715385 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 182 / 638737681044715567 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 169 / 638737681044715736 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 199 / 638737681044715935 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 166 / 638737681044716101 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 151 / 638737681044716252 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 152 / 638737681044716404 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 163 / 638737681044716567 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 145 / 638737681044716712 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 575 / 638737681044717287 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 48 / 638737681044717335 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 156 / 638737681044717491 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 164 / 638737681044717655 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 153 / 638737681044717808 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 153 / 638737681044717961 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 326 / 638737681044718287 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 155 / 638737681044718442 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 194 / 638737681044718636 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 35 / 638737681044718671 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 399 / 638737681044719070 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 55 / 638737681044719125 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 275 / 638737681044719400 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 134 / 638737681044719534 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 167 / 638737681044719701 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 42 / 638737681044719743 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 219 / 638737681044719962 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 186 / 638737681044720148 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 37 / 638737681044720185 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 771 / 638737681044720956 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 61 / 638737681044721017 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 203 / 638737681044721220 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 43 / 638737681044721263 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 205 / 638737681044721468 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 166 / 638737681044721634 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 170 / 638737681044721804 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 154 / 638737681044721958 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 153 / 638737681044722111 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 152 / 638737681044722263 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 164 / 638737681044722427 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 156 / 638737681044722583 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 53 / 638737681044722636 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 157 / 638737681044722793 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 171 / 638737681044722964 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 169 / 638737681044723133 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 37 / 638737681044723170 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 188 / 638737681044723358 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 41 / 638737681044723399 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 684 / 638737681044724083 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 63 / 638737681044724146 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 34 / 638737681044724180 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 216 / 638737681044724396 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 152 / 638737681044724548 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 160 / 638737681044724708 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 43 / 638737681044724751 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 184 / 638737681044724935 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 173 / 638737681044725108 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 149 / 638737681044725257 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 151 / 638737681044725408 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 156 / 638737681044725564 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 170 / 638737681044725734 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 152 / 638737681044725886 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 192 / 638737681044726078 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 15412 / 638737681044741490 / Changed ("file2.txt...22222222222222222222222222222222222222222222222b") 18868 / 638737681044760358 / Changed ("file2.txt...22222222222222222222222222222222222222222222222b") 15019992 / 638737681059780350 / Renamed ("file1....1111111111111111111111111111111111111111111111b")) 420 / 638737681059780770 / Renamed ("file2.txt",...2222222222222222222222222222222222222222222222b")) 15033033 / 638737681074813803 / Changed ("file_1...11111111111111111111111111111111111111111111111c") 352 / 638737681074814155 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 444 / 638737681074814599 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 1248 / 638737681074815847 / Changed ("file_1.txt...11111111111111111111111111111111111111111111111c") 160 / 638737681074816007 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 51 / 638737681074816058 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 269 / 638737681074816327 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 190 / 638737681074816517 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 176 / 638737681074816693 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 367 / 638737681074817060 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 53 / 638737681074817113 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 220 / 638737681074817333 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 47 / 638737681074817380 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 393 / 638737681074817773 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 34 / 638737681074817807 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 388 / 638737681074818195 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 196 / 638737681074818391 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 207 / 638737681074818598 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 319 / 638737681074818917 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 283 / 638737681074819200 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 38 / 638737681074819238 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 227 / 638737681074819465 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 24 / 638737681074819489 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 181 / 638737681074819670 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 40 / 638737681074819710 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 249 / 638737681074819959 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 333 / 638737681074820292 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 103 / 638737681074820395 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 136 / 638737681074820531 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 844 / 638737681074821375 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 75 / 638737681074821450 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 327 / 638737681074821777 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 181 / 638737681074821958 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 48 / 638737681074822006 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 54 / 638737681074822060 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 378 / 638737681074822438 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 64 / 638737681074822502 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 42 / 638737681074822544 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 280 / 638737681074822824 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 49 / 638737681074822873 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 224 / 638737681074823097 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 247 / 638737681074823344 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 184 / 638737681074823528 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 38 / 638737681074823566 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 199 / 638737681074823765 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 38 / 638737681074823803 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 204 / 638737681074824007 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 204 / 638737681074824211 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 116 / 638737681074824327 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 162 / 638737681074824489 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 150 / 638737681074824639 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 38 / 638737681074824677 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 998 / 638737681074825675 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 57 / 638737681074825732 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 184 / 638737681074825916 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 152 / 638737681074826068 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 167 / 638737681074826235 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 45 / 638737681074826280 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 169 / 638737681074826449 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 160 / 638737681074826609 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 139 / 638737681074826748 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 136 / 638737681074826884 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 152 / 638737681074827036 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 410 / 638737681074827446 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 58 / 638737681074827504 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 135 / 638737681074827639 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 133 / 638737681074827772 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 688 / 638737681074828460 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 83 / 638737681074828543 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 193 / 638737681074828736 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 45 / 638737681074828781 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 202 / 638737681074828983 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 54 / 638737681074829037 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 164 / 638737681074829201 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 40 / 638737681074829241 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 173 / 638737681074829414 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 37 / 638737681074829451 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 198 / 638737681074829649 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 38 / 638737681074829687 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 249 / 638737681074829936 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 54 / 638737681074829990 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 768 / 638737681074830758 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 18918 / 638737681074849676 / Changed ("file_2.tx...22222222222222222222222222222222222222222222222c") 122 / 638737681074849798 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 195 / 638737681074849993 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 293 / 638737681074850286 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 68 / 638737681074850354 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 245 / 638737681074850599 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 203 / 638737681074850802 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 54 / 638737681074850856 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 146 / 638737681074851002 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 331 / 638737681074851333 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 194 / 638737681074851527 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 192 / 638737681074851719 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 68 / 638737681074851787 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 186 / 638737681074851973 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 366 / 638737681074852339 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 314 / 638737681074852653 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 35 / 638737681074852688 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 226 / 638737681074852914 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 57 / 638737681074852971 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 161 / 638737681074853132 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 178 / 638737681074853310 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 200 / 638737681074853510 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 236 / 638737681074853746 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 51 / 638737681074853797 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 259 / 638737681074854056 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 51 / 638737681074854107 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 252 / 638737681074854359 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 59 / 638737681074854418 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 159 / 638737681074854577 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 51 / 638737681074854628 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 415 / 638737681074855043 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 173 / 638737681074855216 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 53 / 638737681074855269 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 159 / 638737681074855428 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 62 / 638737681074855490 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 272 / 638737681074855762 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 154 / 638737681074855916 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 249 / 638737681074856165 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 149 / 638737681074856314 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 887 / 638737681074857201 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 68 / 638737681074857269 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 209 / 638737681074857478 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 57 / 638737681074857535 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 153 / 638737681074857688 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 157 / 638737681074857845 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 336 / 638737681074858181 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 223 / 638737681074858404 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 216 / 638737681074858620 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 204 / 638737681074858824 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 182 / 638737681074859006 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 51 / 638737681074859057 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 187 / 638737681074859244 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 194 / 638737681074859438 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 187 / 638737681074859625 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 152 / 638737681074859777 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 172 / 638737681074859949 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 165 / 638737681074860114 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 153 / 638737681074860267 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 146 / 638737681074860413 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 147 / 638737681074860560 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 157 / 638737681074860717 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 210 / 638737681074860927 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 42 / 638737681074860969 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 973 / 638737681074861942 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 106 / 638737681074862048 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 178 / 638737681074862226 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 152 / 638737681074862378 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 148 / 638737681074862526 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 159 / 638737681074862685 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 172 / 638737681074862857 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 39647 / 638737681074902504 / Changed ("file_2.tx...22222222222222222222222222222222222222222222222c") 15008139 / 638737681089910643 / Deleted "file_1.txt" 2280 / 638737681089912923 / Deleted "file_2.txt" [Created ("file1.txt", Some "1a"); Changed ("file1.txt", Some "1a"); Created ("file2.txt", Some "2a"); Changed ("file2.txt", Some "2a"); Changed ("file1.txt", Some "1b"); Changed ("file2.txt", Some "2b"); Renamed ("file1.txt", ("file_1.txt", Some "1b")); Renamed ("file2.txt", ("file_2.txt", Some "2b")); Changed ("file_1.txt", Some "1c"); Changed ("file_2.txt", Some "2c"); Deleted "file_1.txt"; Deleted "file_2.txt"] Some ()
testEventsSorted (test)¶
In [ ]:
//// test
let inline sortEvent event =
match event with
| FileSystemChange.Failure _ -> 0
| FileSystemChange.Created _ -> 1
| FileSystemChange.Changed _ -> 2
| FileSystemChange.Renamed (_oldPath, _) -> 3
| FileSystemChange.Deleted _ -> 4
let inline formatEvents events =
events
|> Seq.toList
|> List.sortBy (snd >> sortEvent)
|> List.choose (fun (ticks, event) ->
match event with
| FileSystemChange.Failure _ ->
None
| FileSystemChange.Changed (path, _) ->
Some (ticks, System.IO.Path.GetFileName path, nameof FileSystemChangeType.Changed)
| FileSystemChange.Created (path, _) ->
Some (ticks, System.IO.Path.GetFileName path, nameof FileSystemChangeType.Created)
| FileSystemChange.Deleted path ->
Some (ticks, System.IO.Path.GetFileName path, nameof FileSystemChangeType.Deleted)
| FileSystemChange.Renamed (_oldPath, (path, _)) ->
Some (ticks, System.IO.Path.GetFileName path, nameof FileSystemChangeType.Renamed)
)
|> List.sortBy (fun (_, path, _) -> path)
|> List.distinctBy (fun (_, path, event) -> path, event)
let inline testEventsSorted
(watchFn : string -> FSharp.Control.AsyncSeq<int64 * FileSystemChange> * IDisposable)
write
=
let struct (tempDir, tempDisposable) =
"FileSystem.testEventsSorted"
|> SpiralCrypto.hash_text
|> SpiralFileSystem.create_temp_dir'
let stream, disposable = watchFn tempDir
let events = System.Collections.Concurrent.ConcurrentBag ()
let inline iter () =
stream
|> FSharp.Control.AsyncSeq.iterAsyncParallel (fun event -> async { events.Add event })
let run = async {
let! _ = iter () |> Async.StartChild
do! Async.Sleep 250
return! write tempDir
}
try
run
|> Async.runWithTimeout 5000
|> _assertEqual (Some ())
finally
disposable.Dispose ()
tempDisposable.Dispose ()
let events = formatEvents events
let eventMap =
events
|> List.map (fun (ticks, path, event) -> path, (event, ticks))
|> List.groupBy fst
|> List.map (fun (path, events) ->
let event, _ticks =
events
|> List.map snd
|> List.sortByDescending snd
|> List.head
path, event
)
|> Map.ofList
let eventList =
events
|> List.map (fun (_ticks, path, event) -> path, event)
eventMap, eventList
create and delete (test)¶
In [ ]:
//// test
let inline write path = async {
let n = 3
for i = 1 to n do
do! $"{i}" |> SpiralFileSystem.write_all_text_async (path </> $"file{i}.txt")
for i = 1 to n do
do! SpiralFileSystem.delete_file_async (path </> $"file{i}.txt") |> Async.Ignore
do! Async.Sleep 150
}
let inline run () =
let eventMap, eventList = testEventsSorted (watchDirectory (fun _ -> false)) write
[
"file1.txt", nameof FileSystemChangeType.Created
"file1.txt", nameof FileSystemChangeType.Changed
"file1.txt", nameof FileSystemChangeType.Deleted
"file2.txt", nameof FileSystemChangeType.Created
"file2.txt", nameof FileSystemChangeType.Changed
"file2.txt", nameof FileSystemChangeType.Deleted
"file3.txt", nameof FileSystemChangeType.Created
"file3.txt", nameof FileSystemChangeType.Changed
"file3.txt", nameof FileSystemChangeType.Deleted
]
|> _sequenceEqual eventList
[
"file1.txt", nameof FileSystemChangeType.Deleted
"file2.txt", nameof FileSystemChangeType.Deleted
"file3.txt", nameof FileSystemChangeType.Deleted
]
|> Map.ofList
|> _sequenceEqual eventMap
run
|> retry_fn 3
|> _assertEqual (Some ())
Some ()
00:00:16 d #5 FileSystem.watchWithFilter / Disposing watch stream / filter: FileName, LastWrite
[("file1.txt", "Created"); ("file1.txt", "Changed"); ("file1.txt", "Deleted"); ("file2.txt", "Created");
("file2.txt", "Changed"); ("file2.txt", "Deleted"); ("file3.txt", "Created"); ("file3.txt", "Changed");
("file3.txt", "Deleted")]
map [("file1.txt", "Deleted"); ("file2.txt", "Deleted"); ("file3.txt", "Deleted")]
Some ()
change (test)¶
In [ ]:
//// test
let inline write path = async {
let n = 2
for i = 1 to n do
do! $"{i}" |> SpiralFileSystem.write_all_text_async (path </> $"file{i}.txt")
for i = 1 to n do
do! "" |> SpiralFileSystem.write_all_text_async (path </> $"file{i}.txt")
for i = 1 to n do
do! SpiralFileSystem.delete_file_async (path </> $"file{i}.txt") |> Async.Ignore
do! Async.Sleep 150
}
let inline run () =
let eventMap, eventList = testEventsSorted (watchDirectory (fun _ -> false)) write
[
"file1.txt", nameof FileSystemChangeType.Created
"file1.txt", nameof FileSystemChangeType.Changed
"file1.txt", nameof FileSystemChangeType.Deleted
"file2.txt", nameof FileSystemChangeType.Created
"file2.txt", nameof FileSystemChangeType.Changed
"file2.txt", nameof FileSystemChangeType.Deleted
]
|> _sequenceEqual eventList
[
"file1.txt", nameof FileSystemChangeType.Deleted
"file2.txt", nameof FileSystemChangeType.Deleted
]
|> Map.ofList
|> _sequenceEqual eventMap
run
|> retry_fn 3
|> _assertEqual (Some ())
Some ()
00:00:17 d #6 FileSystem.watchWithFilter / Disposing watch stream / filter: FileName, LastWrite
[("file1.txt", "Created"); ("file1.txt", "Changed"); ("file1.txt", "Deleted"); ("file2.txt", "Created");
("file2.txt", "Changed"); ("file2.txt", "Deleted")]
map [("file1.txt", "Deleted"); ("file2.txt", "Deleted")]
Some ()
rename (test)¶
In [ ]:
//// test
let inline write path = async {
let n = 2
for i = 1 to n do
do! $"{i}" |> SpiralFileSystem.write_all_text_async (path </> $"file{i}.txt")
for i = 1 to n do
do! path </> $"file{i}.txt" |> SpiralFileSystem.move_file_async (path </> $"file_{i}.txt") |> Async.Ignore
for i = 1 to n do
do! SpiralFileSystem.delete_file_async (path </> $"file_{i}.txt") |> Async.Ignore
do! Async.Sleep 150
}
let inline run () =
let eventMap, eventList = testEventsSorted (watchDirectory (fun _ -> false)) write
[
"file1.txt", nameof FileSystemChangeType.Created
"file1.txt", nameof FileSystemChangeType.Changed
"file2.txt", nameof FileSystemChangeType.Created
"file2.txt", nameof FileSystemChangeType.Changed
"file_1.txt", nameof FileSystemChangeType.Renamed
"file_1.txt", nameof FileSystemChangeType.Deleted
"file_2.txt", nameof FileSystemChangeType.Renamed
"file_2.txt", nameof FileSystemChangeType.Deleted
]
|> _sequenceEqual eventList
[
"file1.txt", nameof FileSystemChangeType.Changed
"file2.txt", nameof FileSystemChangeType.Changed
"file_1.txt", nameof FileSystemChangeType.Deleted
"file_2.txt", nameof FileSystemChangeType.Deleted
]
|> Map.ofList
|> _sequenceEqual eventMap
run
|> retry_fn 3
|> _assertEqual (Some ())
Some ()
00:00:18 d #7 FileSystem.watchWithFilter / Disposing watch stream / filter: FileName, LastWrite
[("file1.txt", "Created"); ("file1.txt", "Changed"); ("file2.txt", "Created"); ("file2.txt", "Changed");
("file_1.txt", "Renamed"); ("file_1.txt", "Deleted"); ("file_2.txt", "Renamed"); ("file_2.txt", "Deleted")]
map [("file1.txt", "Changed"); ("file2.txt", "Changed"); ("file_1.txt", "Deleted"); ("file_2.txt", "Deleted")]
Some ()
full (test)¶
In [ ]:
//// test
let inline write path = async {
let n = 2
for i = 1 to n do
do! $"{i}" |> SpiralFileSystem.write_all_text_async (path </> $"file{i}.txt")
for i = 1 to n do
do! "" |> SpiralFileSystem.write_all_text_async (path </> $"file{i}.txt")
for i = 1 to n do
do! path </> $"file{i}.txt" |> SpiralFileSystem.move_file_async (path </> $"file_{i}.txt") |> Async.Ignore
for i = 1 to n do
do! $"{i}" |> SpiralFileSystem.write_all_text_async (path </> $"file_{i}.txt")
for i = 1 to n do
do! SpiralFileSystem.delete_file_async (path </> $"file_{i}.txt") |> Async.Ignore
do! Async.Sleep 150
}
let inline run () =
let eventMap, eventList = testEventsSorted (watchDirectory (fun _ -> false)) write
[
"file1.txt", nameof FileSystemChangeType.Created
"file1.txt", nameof FileSystemChangeType.Changed
"file2.txt", nameof FileSystemChangeType.Created
"file2.txt", nameof FileSystemChangeType.Changed
"file_1.txt", nameof FileSystemChangeType.Changed
"file_1.txt", nameof FileSystemChangeType.Renamed
"file_1.txt", nameof FileSystemChangeType.Deleted
"file_2.txt", nameof FileSystemChangeType.Changed
"file_2.txt", nameof FileSystemChangeType.Renamed
"file_2.txt", nameof FileSystemChangeType.Deleted
]
|> _sequenceEqual eventList
[
"file1.txt", nameof FileSystemChangeType.Changed
"file2.txt", nameof FileSystemChangeType.Changed
"file_1.txt", nameof FileSystemChangeType.Deleted
"file_2.txt", nameof FileSystemChangeType.Deleted
]
|> Map.ofList
|> _sequenceEqual eventMap
run
|> retry_fn 3
|> _assertEqual (Some ())
Some ()
00:00:19 d #8 FileSystem.watchWithFilter / Disposing watch stream / filter: FileName, LastWrite
[("file1.txt", "Created"); ("file1.txt", "Changed"); ("file2.txt", "Created"); ("file2.txt", "Changed");
("file_1.txt", "Changed"); ("file_1.txt", "Renamed"); ("file_1.txt", "Deleted"); ("file_2.txt", "Changed");
("file_2.txt", "Renamed"); ("file_2.txt", "Deleted")]
map [("file1.txt", "Changed"); ("file2.txt", "Changed"); ("file_1.txt", "Deleted"); ("file_2.txt", "Deleted")]
Some ()