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:03 d #1 FileSystem.watchWithFilter / Disposing watch stream / filter: FileName, LastWrite 00:00:03 d #2 FileSystem.testEventsRaw / eventsLog: 0 / 638701691131248842 / Created ("file1.txt", Some "a1") 11475 / 638701691131260317 / Changed ("file1.txt", Some "a1") 2140 / 638701691131262457 / Created ("file2.txt", Some "a2") 51 / 638701691131262508 / Changed ("file2.txt", Some "a2") 2495601 / 638701691133758109 / Changed ("file1.txt", Some "b1") 261 / 638701691133758370 / Changed ("file1.txt", Some "b1") 4993 / 638701691133763363 / Changed ("file2.txt", Some "b2") 224 / 638701691133763587 / Changed ("file2.txt", Some "b2") 2544215 / 638701691136307802 / Renamed ("file1.txt", ("file_1.txt", Some "b1")) 8740 / 638701691136316542 / Renamed ("file2.txt", ("file_2.txt", Some "b2")) 2517388 / 638701691138833930 / Changed ("file_1.txt", Some "c1") 1960 / 638701691138835890 / Changed ("file_1.txt", Some "c1") 3422 / 638701691138839312 / Changed ("file_2.txt", Some "c2") 355 / 638701691138839667 / Changed ("file_2.txt", Some "c2") 2521028 / 638701691141360695 / Deleted "file_1.txt" 826 / 638701691141361521 / 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 / 638701691157567664 / Created ("file1.txt", ...11111111111111111111111111111111111111111111111a") 3514 / 638701691157571178 / Changed ("file1.txt"...11111111111111111111111111111111111111111111111a") 587 / 638701691157571765 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111a") 80 / 638701691157571845 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111a") 10389 / 638701691157582234 / Changed ("file1.txt...11111111111111111111111111111111111111111111111a") 29707 / 638701691157611941 / Created ("file2.txt...22222222222222222222222222222222222222222222222a") 202 / 638701691157612143 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 82 / 638701691157612225 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 626 / 638701691157612851 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 479 / 638701691157613330 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 3531 / 638701691157616861 / Changed ("file2.txt"...22222222222222222222222222222222222222222222222a") 220 / 638701691157617081 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 153 / 638701691157617234 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 55 / 638701691157617289 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 386 / 638701691157617675 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 543 / 638701691157618218 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 231 / 638701691157618449 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 269 / 638701691157618718 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 128 / 638701691157618846 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 300 / 638701691157619146 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 171 / 638701691157619317 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 175 / 638701691157619492 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 162 / 638701691157619654 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 162 / 638701691157619816 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 186 / 638701691157620002 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 145 / 638701691157620147 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 211 / 638701691157620358 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 169 / 638701691157620527 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 184 / 638701691157620711 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 161 / 638701691157620872 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 168 / 638701691157621040 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 155 / 638701691157621195 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 188 / 638701691157621383 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 166 / 638701691157621549 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 135 / 638701691157621684 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 203 / 638701691157621887 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 168 / 638701691157622055 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 161 / 638701691157622216 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 223 / 638701691157622439 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 182 / 638701691157622621 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 58 / 638701691157622679 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 338 / 638701691157623017 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 62 / 638701691157623079 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 244 / 638701691157623323 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 253 / 638701691157623576 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222a") 65 / 638701691157623641 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222a") 12231 / 638701691157635872 / Changed ("file2.txt...22222222222222222222222222222222222222222222222a") 15031474 / 638701691172667346 / Changed ("file1....11111111111111111111111111111111111111111111111b") 345 / 638701691172667691 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 588 / 638701691172668279 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 876 / 638701691172669155 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 94 / 638701691172669249 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 249 / 638701691172669498 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 53 / 638701691172669551 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 224 / 638701691172669775 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 71 / 638701691172669846 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 198 / 638701691172670044 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 54 / 638701691172670098 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 221 / 638701691172670319 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 51 / 638701691172670370 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 227 / 638701691172670597 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 719 / 638701691172671316 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 110 / 638701691172671426 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 340 / 638701691172671766 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 260 / 638701691172672026 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 584 / 638701691172672610 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 72 / 638701691172672682 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 174 / 638701691172672856 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 181 / 638701691172673037 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 140 / 638701691172673177 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 205 / 638701691172673382 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 144 / 638701691172673526 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 177 / 638701691172673703 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 3408 / 638701691172677111 / Changed ("file1.txt"...11111111111111111111111111111111111111111111111b") 94 / 638701691172677205 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 311 / 638701691172677516 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 1079 / 638701691172678595 / Changed ("file1.txt"...11111111111111111111111111111111111111111111111b") 100 / 638701691172678695 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 291 / 638701691172678986 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 156 / 638701691172679142 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 203 / 638701691172679345 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 287 / 638701691172679632 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 214 / 638701691172679846 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 199 / 638701691172680045 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 169 / 638701691172680214 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 187 / 638701691172680401 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 193 / 638701691172680594 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 194 / 638701691172680788 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 181 / 638701691172680969 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 167 / 638701691172681136 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 159 / 638701691172681295 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 185 / 638701691172681480 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 902 / 638701691172682382 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 104 / 638701691172682486 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 241 / 638701691172682727 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 445 / 638701691172683172 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 156 / 638701691172683328 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 168 / 638701691172683496 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 199 / 638701691172683695 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 163 / 638701691172683858 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 190 / 638701691172684048 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 150 / 638701691172684198 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 2818 / 638701691172687016 / Changed ("file1.txt"...11111111111111111111111111111111111111111111111b") 84 / 638701691172687100 / Changed ("file1.txt", ...11111111111111111111111111111111111111111111111b") 147 / 638701691172687247 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 314 / 638701691172687561 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 325 / 638701691172687886 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 252 / 638701691172688138 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 249 / 638701691172688387 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 252 / 638701691172688639 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 245 / 638701691172688884 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 225 / 638701691172689109 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 248 / 638701691172689357 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 267 / 638701691172689624 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 458 / 638701691172690082 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 254 / 638701691172690336 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 275 / 638701691172690611 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 196 / 638701691172690807 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 168 / 638701691172690975 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 215 / 638701691172691190 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 297 / 638701691172691487 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 221 / 638701691172691708 / Changed ("file1.txt",...11111111111111111111111111111111111111111111111b") 1257 / 638701691172692965 / Changed ("file1.txt"...11111111111111111111111111111111111111111111111b") 33705 / 638701691172726670 / Changed ("file2.txt...22222222222222222222222222222222222222222222222b") 172 / 638701691172726842 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 441 / 638701691172727283 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 316 / 638701691172727599 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 278 / 638701691172727877 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 306 / 638701691172728183 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 301 / 638701691172728484 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 250 / 638701691172728734 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 243 / 638701691172728977 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 62 / 638701691172729039 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 166 / 638701691172729205 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 193 / 638701691172729398 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 169 / 638701691172729567 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 238 / 638701691172729805 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 57 / 638701691172729862 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 262 / 638701691172730124 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 81 / 638701691172730205 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 184 / 638701691172730389 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 59 / 638701691172730448 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 272 / 638701691172730720 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 162 / 638701691172730882 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 238 / 638701691172731120 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 65 / 638701691172731185 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 185 / 638701691172731370 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 71 / 638701691172731441 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 249 / 638701691172731690 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 153 / 638701691172731843 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 271 / 638701691172732114 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 75 / 638701691172732189 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 176 / 638701691172732365 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 59 / 638701691172732424 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 257 / 638701691172732681 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 69 / 638701691172732750 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 175 / 638701691172732925 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 458 / 638701691172733383 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 91 / 638701691172733474 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 54 / 638701691172733528 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 273 / 638701691172733801 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 69 / 638701691172733870 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 66 / 638701691172733936 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 250 / 638701691172734186 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 431 / 638701691172734617 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 376 / 638701691172734993 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 557 / 638701691172735550 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 594 / 638701691172736144 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 98 / 638701691172736242 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 257 / 638701691172736499 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 85 / 638701691172736584 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 193 / 638701691172736777 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 417 / 638701691172737194 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 529 / 638701691172737723 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 78 / 638701691172737801 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 185 / 638701691172737986 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 276 / 638701691172738262 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 270 / 638701691172738532 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 155 / 638701691172738687 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 184 / 638701691172738871 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 132 / 638701691172739003 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 249 / 638701691172739252 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 190 / 638701691172739442 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 153 / 638701691172739595 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 142 / 638701691172739737 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 195 / 638701691172739932 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 172 / 638701691172740104 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 268 / 638701691172740372 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 255 / 638701691172740627 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 252 / 638701691172740879 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 153 / 638701691172741032 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 249 / 638701691172741281 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 178 / 638701691172741459 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 182 / 638701691172741641 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 197 / 638701691172741838 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 56 / 638701691172741894 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 235 / 638701691172742129 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 54 / 638701691172742183 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 236 / 638701691172742419 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 232 / 638701691172742651 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 421 / 638701691172743072 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 502 / 638701691172743574 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 84 / 638701691172743658 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 237 / 638701691172743895 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 492 / 638701691172744387 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 80 / 638701691172744467 / Changed ("file2.txt", ...22222222222222222222222222222222222222222222222b") 250 / 638701691172744717 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 165 / 638701691172744882 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 204 / 638701691172745086 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 178 / 638701691172745264 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 190 / 638701691172745454 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 169 / 638701691172745623 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 193 / 638701691172745816 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 160 / 638701691172745976 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 220 / 638701691172746196 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 188 / 638701691172746384 / Changed ("file2.txt",...22222222222222222222222222222222222222222222222b") 28682 / 638701691172775066 / Changed ("file2.txt...22222222222222222222222222222222222222222222222b") 15032796 / 638701691187807862 / Renamed ("file1....1111111111111111111111111111111111111111111111b")) 397 / 638701691187808259 / Renamed ("file2.txt",...2222222222222222222222222222222222222222222222b")) 15050944 / 638701691202859203 / Changed ("file_1...11111111111111111111111111111111111111111111111c") 518 / 638701691202859721 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 539 / 638701691202860260 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 65 / 638701691202860325 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 226 / 638701691202860551 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 232 / 638701691202860783 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 513 / 638701691202861296 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 566 / 638701691202861862 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 287 / 638701691202862149 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 382 / 638701691202862531 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 407 / 638701691202862938 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 410 / 638701691202863348 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 328 / 638701691202863676 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 302 / 638701691202863978 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 296 / 638701691202864274 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 454 / 638701691202864728 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 294 / 638701691202865022 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 306 / 638701691202865328 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 289 / 638701691202865617 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 247 / 638701691202865864 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 234 / 638701691202866098 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 286 / 638701691202866384 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 333 / 638701691202866717 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 270 / 638701691202866987 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 327 / 638701691202867314 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 318 / 638701691202867632 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 496 / 638701691202868128 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 556 / 638701691202868684 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 323 / 638701691202869007 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 372 / 638701691202869379 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 518 / 638701691202869897 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 201 / 638701691202870098 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 246 / 638701691202870344 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 204 / 638701691202870548 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 153 / 638701691202870701 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 172 / 638701691202870873 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 168 / 638701691202871041 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 162 / 638701691202871203 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 163 / 638701691202871366 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 181 / 638701691202871547 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 161 / 638701691202871708 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 196 / 638701691202871904 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 154 / 638701691202872058 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 170 / 638701691202872228 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 169 / 638701691202872397 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 181 / 638701691202872578 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 165 / 638701691202872743 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 159 / 638701691202872902 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 188 / 638701691202873090 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 180 / 638701691202873270 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 154 / 638701691202873424 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 186 / 638701691202873610 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 328 / 638701691202873938 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 379 / 638701691202874317 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 334 / 638701691202874651 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 318 / 638701691202874969 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 395 / 638701691202875364 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 653 / 638701691202876017 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 224 / 638701691202876241 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 57 / 638701691202876298 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 169 / 638701691202876467 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 180 / 638701691202876647 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 196 / 638701691202876843 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 167 / 638701691202877010 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 136 / 638701691202877146 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 165 / 638701691202877311 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 923 / 638701691202878234 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 71 / 638701691202878305 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 124 / 638701691202878429 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 202 / 638701691202878631 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 222 / 638701691202878853 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 184 / 638701691202879037 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 196 / 638701691202879233 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 123 / 638701691202879356 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 1620 / 638701691202880976 / Changed ("file_1.txt...11111111111111111111111111111111111111111111111c") 72 / 638701691202881048 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 212 / 638701691202881260 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 177 / 638701691202881437 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 157 / 638701691202881594 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 165 / 638701691202881759 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 169 / 638701691202881928 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 179 / 638701691202882107 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 157 / 638701691202882264 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 162 / 638701691202882426 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 215 / 638701691202882641 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 179 / 638701691202882820 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 183 / 638701691202883003 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 153 / 638701691202883156 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 158 / 638701691202883314 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 655 / 638701691202883969 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 72 / 638701691202884041 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 114 / 638701691202884155 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 177 / 638701691202884332 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 185 / 638701691202884517 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 542 / 638701691202885059 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 64 / 638701691202885123 / Changed ("file_1.txt",...11111111111111111111111111111111111111111111111c") 135 / 638701691202885258 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 150 / 638701691202885408 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 167 / 638701691202885575 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 200 / 638701691202885775 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 185 / 638701691202885960 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 163 / 638701691202886123 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 167 / 638701691202886290 / Changed ("file_1.txt"...11111111111111111111111111111111111111111111111c") 46593 / 638701691202932883 / Changed ("file_2.tx...22222222222222222222222222222222222222222222222c") 483 / 638701691202933366 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 269 / 638701691202933635 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 306 / 638701691202933941 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 321 / 638701691202934262 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 84 / 638701691202934346 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 158 / 638701691202934504 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 354 / 638701691202934858 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 66 / 638701691202934924 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 279 / 638701691202935203 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 205 / 638701691202935408 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 256 / 638701691202935664 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 61 / 638701691202935725 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 177 / 638701691202935902 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 246 / 638701691202936148 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 52 / 638701691202936200 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 217 / 638701691202936417 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 54 / 638701691202936471 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 213 / 638701691202936684 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 245 / 638701691202936929 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 64 / 638701691202936993 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 217 / 638701691202937210 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 55 / 638701691202937265 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 202 / 638701691202937467 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 193 / 638701691202937660 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 52 / 638701691202937712 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 227 / 638701691202937939 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 235 / 638701691202938174 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 290 / 638701691202938464 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 57 / 638701691202938521 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 340 / 638701691202938861 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 64 / 638701691202938925 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 349 / 638701691202939274 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 63 / 638701691202939337 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 334 / 638701691202939671 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 178 / 638701691202939849 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 150 / 638701691202939999 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 262 / 638701691202940261 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 48 / 638701691202940309 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 194 / 638701691202940503 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 151 / 638701691202940654 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 145 / 638701691202940799 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 164 / 638701691202940963 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 606 / 638701691202941569 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 74 / 638701691202941643 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 145 / 638701691202941788 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 244 / 638701691202942032 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 64 / 638701691202942096 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 297 / 638701691202942393 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 57 / 638701691202942450 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 330 / 638701691202942780 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 58 / 638701691202942838 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 262 / 638701691202943100 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 183 / 638701691202943283 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 221 / 638701691202943504 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 167 / 638701691202943671 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 137 / 638701691202943808 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 241 / 638701691202944049 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 191 / 638701691202944240 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 210 / 638701691202944450 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 156 / 638701691202944606 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 220 / 638701691202944826 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 159 / 638701691202944985 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 148 / 638701691202945133 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 502 / 638701691202945635 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 252 / 638701691202945887 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 201 / 638701691202946088 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 421 / 638701691202946509 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 317 / 638701691202946826 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 310 / 638701691202947136 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 304 / 638701691202947440 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 322 / 638701691202947762 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 302 / 638701691202948064 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 321 / 638701691202948385 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 303 / 638701691202948688 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 298 / 638701691202948986 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 304 / 638701691202949290 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 325 / 638701691202949615 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 334 / 638701691202949949 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 307 / 638701691202950256 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 319 / 638701691202950575 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 312 / 638701691202950887 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 304 / 638701691202951191 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 303 / 638701691202951494 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 305 / 638701691202951799 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 302 / 638701691202952101 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 325 / 638701691202952426 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 322 / 638701691202952748 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 313 / 638701691202953061 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 318 / 638701691202953379 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 313 / 638701691202953692 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 306 / 638701691202953998 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 295 / 638701691202954293 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 326 / 638701691202954619 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 312 / 638701691202954931 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 402 / 638701691202955333 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 377 / 638701691202955710 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 353 / 638701691202956063 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 350 / 638701691202956413 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 331 / 638701691202956744 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 342 / 638701691202957086 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 409 / 638701691202957495 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 347 / 638701691202957842 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 355 / 638701691202958197 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 331 / 638701691202958528 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 341 / 638701691202958869 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 375 / 638701691202959244 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 331 / 638701691202959575 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 369 / 638701691202959944 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 380 / 638701691202960324 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 376 / 638701691202960700 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 202 / 638701691202960902 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 227 / 638701691202961129 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 270 / 638701691202961399 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 257 / 638701691202961656 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 243 / 638701691202961899 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 245 / 638701691202962144 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 239 / 638701691202962383 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 228 / 638701691202962611 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 292 / 638701691202962903 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 289 / 638701691202963192 / Changed ("file_2.txt"...22222222222222222222222222222222222222222222222c") 81 / 638701691202963273 / Changed ("file_2.txt",...22222222222222222222222222222222222222222222222c") 14990807 / 638701691217954080 / Deleted "file_1.txt" 2237 / 638701691217956317 / 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 ()