11
11
12
12
module SKFS;
13
13
14
+ /*****************************************************************************/
15
+ /* Unique number generator. */
16
+ /*****************************************************************************/
17
+
18
+ @cpp_extern("SKIP_genSym")
19
+ native fun genSym(Int): Int;
20
+
14
21
/*****************************************************************************/
15
22
/* Constants */
16
23
/*****************************************************************************/
@@ -190,7 +197,7 @@ mutable class Context{
190
197
mutable pwd: String = "/",
191
198
mutable dirs: Dirs = Dirs{},
192
199
mutable reads: SortedSet<Path> = SortedSet[],
193
- mutable time: Int = 1 ,
200
+ mutable time: Int = 0 ,
194
201
mutable tick: Int = 1,
195
202
mutable lazyCapacity: Int = 10,
196
203
mutable toUpdate: SortedMap<(Int, Int), Arrow> = SortedMap[],
@@ -493,6 +500,7 @@ mutable class Context{
493
500
};
494
501
495
502
this.!tick = this.tick + 1;
503
+ _ = this.timeStamp();
496
504
497
505
this.updateLazyGets();
498
506
@@ -584,7 +592,7 @@ mutable class Context{
584
592
}
585
593
586
594
mutable fun timeStamp(): Int {
587
- this.!time = this.time + 1;
595
+ this.!time = genSym( this.time + 1) ;
588
596
this.time
589
597
}
590
598
@@ -646,7 +654,7 @@ mutable class Context{
646
654
totalSize = fixedData.data.size();
647
655
creator = this.currentArrow();
648
656
dir = EagerDir{time, input => true, dirName, fixedData, totalSize, creator};
649
- this.!dirs = this.dirs.set(dir.time, dirName, dir);
657
+ this.setDir( dirName, dir);
650
658
this.!newDirs = this.newDirs.add(dirName);
651
659
}
652
660
@@ -665,26 +673,13 @@ mutable class Context{
665
673
totalSize = fixedData.data.size();
666
674
creator = this.currentArrow();
667
675
dir = EagerDir{time, input => true, dirName, fixedData, totalSize, creator};
668
- this.!dirs = this.dirs.set(dir.time, dirName, dir);
676
+ this.setDir( dirName, dir);
669
677
this.!newDirs = this.newDirs.add(dirName);
670
678
EHandle(conv, dirName)
671
679
}
672
680
673
681
mutable fun setDir(dirName: DirName, dir: Dir): void {
674
- /*
675
- dirNamePwdStr = this.pwd.join("/");
676
- dirNameStr = dirName.toString();
677
- dirNameArr = dirNameStr.split("/");
678
- if (dirNameArr.size() < 2) {
679
- error(`Invalid directory name: ${dirNameStr}`);
680
- };
681
- lastDirName = dirNameArr[dirNameArr.size() - 2];
682
- if (dirNamePwdStr + lastDirName + "/" != dirNameStr) {
683
- error(`Cannot create directory ${dirNameStr} from path ${dirNamePwdStr}`);
684
- };
685
- */
686
- // TODO: re-enable this when the dirNames are represented as lists
687
- this.!dirs = this.dirs.set(dir.getTime(), dirName, dir);
682
+ this.!dirs = this.dirs.set(this.timeStamp(), dirName, dir);
688
683
}
689
684
690
685
mutable fun getDir(dirName: DirName): Dir {
@@ -826,6 +821,35 @@ class Dirs{state: DMap<DirName, Dir> = DMap::empty()} {
826
821
}
827
822
}
828
823
824
+ @cpp_export("SKIP_syncContext")
825
+ fun syncContext(txTime: Int, newRoot: Context, ctx: mutable Context): void {
826
+ if (txTime == newRoot.time) return void;
827
+
828
+ context = Context::fromSaved(newRoot);
829
+
830
+ changedDirNames = ctx.dirs.state.getChangesAfter(txTime);
831
+ for (dirName in changedDirNames) {
832
+ ctx.unsafeMaybeGetDir(dirName) match {
833
+ | Some(dir @ EagerDir{input => true}) ->
834
+ changedKeys = dir.getChangesAfter(txTime);
835
+ context.unsafeMaybeGetDir(dirName) match {
836
+ | None() -> context.mkdirMulti(dirName, Array[])
837
+ | Some(EagerDir{input => true}) -> void
838
+ | Some(_) -> invariant_violation("Error: incompactible dir types")
839
+ };
840
+ for (key in changedKeys) {
841
+ values = dir.getArrayRaw(key);
842
+ inputDir = context.unsafeMaybeGetEagerDir(dirName).fromSome();
843
+ inputDir.writeArray(context, key, values);
844
+ }
845
+ | _ -> void
846
+ }
847
+ };
848
+
849
+ context.update();
850
+ ctx.replaceFromSaved(context.clone());
851
+ }
852
+
829
853
@cpp_extern
830
854
private native base class Obstack
831
855
@@ -843,7 +867,7 @@ private native fun destroyObstackWithValue<T>(Obstack, List<T>): List<T>;
843
867
844
868
@debug
845
869
@cpp_extern("SKIP_context_sync")
846
- private native fun gContextSync(Context): Context;
870
+ private native fun gContextSync(Int, Context, Context): Context;
847
871
848
872
@debug
849
873
@cpp_extern("SKIP_context_init")
@@ -869,25 +893,38 @@ native fun disableGC(): void;
869
893
@cpp_extern("SKIP_enable_GC")
870
894
native fun enableGC(): void;
871
895
896
+ base class ContextOp {
897
+ children =
898
+ | CContinue(Context)
899
+ | CStop(Context)
900
+ | CAbort()
901
+ }
902
+
872
903
@cpp_noinline
873
904
fun runWithGcReturnContext(
874
905
origContext: Context,
875
- f: Context ~> ?Context ,
906
+ f: Context ~> ContextOp ,
876
907
): mutable Context {
877
908
context = gContextInit(origContext);
909
+ startTime = context.time;
878
910
loop {
879
911
pos = newObstack();
880
912
newContextOpt = f(context);
881
913
newContextOpt match {
882
- | None() -> return Context::fromSaved(context)
883
- | Some(newContext) ->
884
- !context = gContextSync(newContext);
914
+ | CAbort() -> return Context::fromSaved(context)
915
+ | CContinue(newContext) ->
916
+ !context = gContextSync(startTime, context, newContext);
917
+ !startTime = context.time;
885
918
destroyObstack(pos)
919
+ | CStop(newContext) ->
920
+ !context = gContextSync(startTime, context, newContext);
921
+ !startTime = context.time;
922
+ return Context::fromSaved(context)
886
923
}
887
924
}
888
925
}
889
926
890
- fun runWithGc(origContext: Context, f: Context ~> ?Context ): void {
927
+ fun runWithGc(origContext: Context, f: Context ~> ContextOp ): void {
891
928
_ = runWithGcReturnContext(origContext, f);
892
929
}
893
930
0 commit comments