[Unison-hackers] [unison-svn] r393 - trunk/src
vouillon@seas.upenn.edu
vouillon at seas.upenn.edu
Wed Jan 6 16:20:15 EST 2010
Author: vouillon
Date: 2010-01-06 16:20:12 -0500 (Wed, 06 Jan 2010)
New Revision: 393
Added:
trunk/src/fpcache.ml
trunk/src/fpcache.mli
Modified:
trunk/src/.depend
trunk/src/Makefile.OCaml
trunk/src/RECENTNEWS
trunk/src/copy.ml
trunk/src/mkProjectInfo.ml
trunk/src/path.ml
trunk/src/path.mli
trunk/src/update.ml
trunk/src/update.mli
Log:
* Implemented an on-disk file fingerprint cache to speed-up update
detection after a crash: this way, Unison does not have do recompute
all the file fingerprints from scratch.
Modified: trunk/src/.depend
===================================================================
--- trunk/src/.depend 2010-01-05 15:42:43 UTC (rev 392)
+++ trunk/src/.depend 2010-01-06 21:20:12 UTC (rev 393)
@@ -13,6 +13,7 @@
lwt/lwt.cmi common.cmi
fileutil.cmi:
fingerprint.cmi: uutil.cmi path.cmi fspath.cmi
+fpcache.cmi:
fs.cmi: system/system_intf.cmo fspath.cmi
fspath.cmi: system.cmi path.cmi name.cmi
globals.cmi: ubase/prefs.cmi pred.cmi path.cmi lwt/lwt.cmi common.cmi
@@ -35,10 +36,10 @@
transfer.cmi: uutil.cmi lwt/lwt.cmi bytearray.cmi
transport.cmi: uutil.cmi lwt/lwt.cmi common.cmi
tree.cmi:
+ui.cmi:
uicommon.cmi: uutil.cmi ubase/prefs.cmi path.cmi lwt/lwt.cmi common.cmi
+uigtk.cmi: uicommon.cmi
uigtk2.cmi: uicommon.cmi
-uigtk.cmi: uicommon.cmi
-ui.cmi:
uitext.cmi: uicommon.cmi
unicode.cmi:
update.cmi: uutil.cmi tree.cmi props.cmi path.cmi osx.cmi os.cmi name.cmi \
@@ -93,6 +94,12 @@
fileutil.cmx: fileutil.cmi
fingerprint.cmo: uutil.cmi ubase/util.cmi fspath.cmi fs.cmi fingerprint.cmi
fingerprint.cmx: uutil.cmx ubase/util.cmx fspath.cmx fs.cmx fingerprint.cmi
+fpcache.cmo: uutil.cmi ubase/util.cmi ubase/trace.cmi system.cmi \
+ ubase/safelist.cmi props.cmi path.cmi osx.cmi os.cmi fileinfo.cmi \
+ fpcache.cmi
+fpcache.cmx: uutil.cmx ubase/util.cmx ubase/trace.cmx system.cmx \
+ ubase/safelist.cmx props.cmx path.cmx osx.cmx os.cmx fileinfo.cmx \
+ fpcache.cmi
fs.cmo: fspath.cmi fs.cmi
fs.cmx: fspath.cmx fs.cmi
fspath.cmo: uutil.cmi ubase/util.cmi system.cmi ubase/rx.cmi path.cmi \
@@ -105,10 +112,10 @@
globals.cmx: ubase/util.cmx ubase/trace.cmx ubase/safelist.cmx remote.cmx \
ubase/prefs.cmx pred.cmx path.cmx os.cmx name.cmx lwt/lwt_util.cmx \
lwt/lwt_unix.cmx lwt/lwt.cmx common.cmx clroot.cmx globals.cmi
+linkgtk.cmo: uigtk.cmi main.cmo
+linkgtk.cmx: uigtk.cmx main.cmx
linkgtk2.cmo: uigtk2.cmi main.cmo
linkgtk2.cmx: uigtk2.cmx main.cmx
-linkgtk.cmo: uigtk.cmi main.cmo
-linkgtk.cmx: uigtk.cmx main.cmx
linktext.cmo: uitext.cmi main.cmo
linktext.cmx: uitext.cmx main.cmx
lock.cmo: ubase/util.cmi system.cmi lock.cmi
@@ -213,6 +220,16 @@
recon.cmx props.cmx ubase/prefs.cmx path.cmx osx.cmx os.cmx name.cmx \
lwt/lwt_unix.cmx lwt/lwt.cmx globals.cmx fspath.cmx files.cmx \
fileinfo.cmx common.cmx clroot.cmx case.cmx uicommon.cmi
+uigtk.cmo: uutil.cmi ubase/util.cmi update.cmi uitext.cmi uicommon.cmi \
+ transport.cmi ubase/trace.cmi system.cmi strings.cmi sortri.cmi \
+ ubase/safelist.cmi remote.cmi recon.cmi ubase/prefs.cmi pixmaps.cmo \
+ path.cmi os.cmi lwt/lwt_util.cmi lwt/lwt_unix.cmi lwt/lwt.cmi globals.cmi \
+ files.cmi common.cmi clroot.cmi uigtk.cmi
+uigtk.cmx: uutil.cmx ubase/util.cmx update.cmx uitext.cmx uicommon.cmx \
+ transport.cmx ubase/trace.cmx system.cmx strings.cmx sortri.cmx \
+ ubase/safelist.cmx remote.cmx recon.cmx ubase/prefs.cmx pixmaps.cmx \
+ path.cmx os.cmx lwt/lwt_util.cmx lwt/lwt_unix.cmx lwt/lwt.cmx globals.cmx \
+ files.cmx common.cmx clroot.cmx uigtk.cmi
uigtk2.cmo: uutil.cmi ubase/util.cmi update.cmi unicode.cmi uitext.cmi \
uicommon.cmi transport.cmi ubase/trace.cmi system.cmi strings.cmi \
sortri.cmi ubase/safelist.cmi remote.cmi recon.cmi ubase/prefs.cmi \
@@ -223,16 +240,6 @@
sortri.cmx ubase/safelist.cmx remote.cmx recon.cmx ubase/prefs.cmx \
pixmaps.cmx path.cmx os.cmx lwt/lwt_util.cmx lwt/lwt_unix.cmx lwt/lwt.cmx \
globals.cmx files.cmx common.cmx clroot.cmx case.cmx uigtk2.cmi
-uigtk.cmo: uutil.cmi ubase/util.cmi update.cmi uitext.cmi uicommon.cmi \
- transport.cmi ubase/trace.cmi system.cmi strings.cmi sortri.cmi \
- ubase/safelist.cmi remote.cmi recon.cmi ubase/prefs.cmi pixmaps.cmo \
- path.cmi os.cmi lwt/lwt_util.cmi lwt/lwt_unix.cmi lwt/lwt.cmi globals.cmi \
- files.cmi common.cmi clroot.cmi uigtk.cmi
-uigtk.cmx: uutil.cmx ubase/util.cmx update.cmx uitext.cmx uicommon.cmx \
- transport.cmx ubase/trace.cmx system.cmx strings.cmx sortri.cmx \
- ubase/safelist.cmx remote.cmx recon.cmx ubase/prefs.cmx pixmaps.cmx \
- path.cmx os.cmx lwt/lwt_util.cmx lwt/lwt_unix.cmx lwt/lwt.cmx globals.cmx \
- files.cmx common.cmx clroot.cmx uigtk.cmi
uimacbridge.cmo: xferhint.cmi uutil.cmi ubase/util.cmi update.cmi \
uicommon.cmi transport.cmi ubase/trace.cmi terminal.cmi system.cmi \
stasher.cmi ubase/safelist.cmi remote.cmi recon.cmi ubase/prefs.cmi \
@@ -271,12 +278,12 @@
system.cmi ubase/safelist.cmi remote.cmi props.cmi ubase/proplist.cmi \
ubase/prefs.cmi pred.cmi path.cmi osx.cmi os.cmi name.cmi ubase/myMap.cmi \
lwt/lwt_unix.cmi lwt/lwt.cmi lock.cmi globals.cmi fspath.cmi fs.cmi \
- fingerprint.cmi fileinfo.cmi common.cmi case.cmi update.cmi
+ fpcache.cmi fingerprint.cmi fileinfo.cmi common.cmi case.cmi update.cmi
update.cmx: xferhint.cmx uutil.cmx ubase/util.cmx tree.cmx ubase/trace.cmx \
system.cmx ubase/safelist.cmx remote.cmx props.cmx ubase/proplist.cmx \
ubase/prefs.cmx pred.cmx path.cmx osx.cmx os.cmx name.cmx ubase/myMap.cmx \
lwt/lwt_unix.cmx lwt/lwt.cmx lock.cmx globals.cmx fspath.cmx fs.cmx \
- fingerprint.cmx fileinfo.cmx common.cmx case.cmx update.cmi
+ fpcache.cmx fingerprint.cmx fileinfo.cmx common.cmx case.cmx update.cmi
uutil.cmo: ubase/util.cmi ubase/trace.cmi ubase/projectInfo.cmo uutil.cmi
uutil.cmx: ubase/util.cmx ubase/trace.cmx ubase/projectInfo.cmx uutil.cmi
xferhint.cmo: ubase/util.cmi ubase/trace.cmi ubase/prefs.cmi path.cmi os.cmi \
Modified: trunk/src/Makefile.OCaml
===================================================================
--- trunk/src/Makefile.OCaml 2010-01-05 15:42:43 UTC (rev 392)
+++ trunk/src/Makefile.OCaml 2010-01-06 21:20:12 UTC (rev 393)
@@ -214,7 +214,7 @@
props.cmo fileinfo.cmo os.cmo lock.cmo clroot.cmo common.cmo \
tree.cmo checksum.cmo terminal.cmo \
transfer.cmo xferhint.cmo remote.cmo globals.cmo \
- update.cmo copy.cmo stasher.cmo \
+ fpcache.cmo update.cmo copy.cmo stasher.cmo \
files.cmo sortri.cmo recon.cmo transport.cmo \
strings.cmo uicommon.cmo uitext.cmo test.cmo
Modified: trunk/src/RECENTNEWS
===================================================================
--- trunk/src/RECENTNEWS 2010-01-05 15:42:43 UTC (rev 392)
+++ trunk/src/RECENTNEWS 2010-01-06 21:20:12 UTC (rev 393)
@@ -1,3 +1,10 @@
+CHANGES FROM VERSION 2.38.5
+
+* Implemented an on-disk file fingerprint cache to speed-up update
+ detection after a crash: this way, Unison does not have do recompute
+ all the file fingerprints from scratch.
+
+-------------------------------
CHANGES FROM VERSION 2.38.0
* Roll back a previous "fix" for a permission-setting issue and
Modified: trunk/src/copy.ml
===================================================================
--- trunk/src/copy.ml 2010-01-05 15:42:43 UTC (rev 392)
+++ trunk/src/copy.ml 2010-01-06 21:20:12 UTC (rev 393)
@@ -55,7 +55,7 @@
let dataClearlyUnchanged =
not clearlyModified
&& Props.same_time info.Fileinfo.desc archDesc
- && not (Update.excelFile pathFrom)
+ && not (Fpcache.excelFile pathFrom)
&& match archStamp with
Some (Fileinfo.InodeStamp inode) -> info.Fileinfo.inode = inode
| Some (Fileinfo.CtimeStamp ctime) -> true
Added: trunk/src/fpcache.ml
===================================================================
--- trunk/src/fpcache.ml (rev 0)
+++ trunk/src/fpcache.ml 2010-01-06 21:20:12 UTC (rev 393)
@@ -0,0 +1,251 @@
+(* Unison file synchronizer: src/fpcache.ml *)
+(* Copyright 1999-2010, Benjamin C. Pierce
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*)
+
+let debug = Trace.debug "fpcache"
+
+(* In-memory cache *)
+
+module PathTbl =
+ Hashtbl.Make
+ (struct
+ type t = string
+ let equal (s1 : string) (s2 : string) = s1 = s2
+ let hash = Hashtbl.hash
+ end)
+
+let tbl = PathTbl.create 101
+
+(* Information for writing to the on-disk cache *)
+
+type entry = int * string * (Fileinfo.t * Os.fullfingerprint)
+
+type state =
+ { oc : out_channel;
+ mutable count : int;
+ mutable size : Uutil.Filesize.t;
+ mutable last : string;
+ mutable queue : entry list }
+
+let state = ref None
+
+(****)
+
+(* Path compression and decompression (use delta from previous path for
+ compression) *)
+
+let decompress st i path =
+ let l = String.length path in
+ let s = String.create (l + i) in
+ String.blit !st 0 s 0 i;
+ String.blit path 0 s i l;
+ st := s;
+ s
+
+let compress state path =
+ let s = state.last in
+ let p = Path.toString path in
+ let l = String.length s in
+ let i = ref 0 in
+ while !i < l && p.[!i] = s.[!i] do incr i done;
+ state.last <- p;
+ (!i, String.sub p !i (String.length p - !i))
+
+(*****)
+
+(* Read and write a chunk of file fingerprints from the cache *)
+
+let read st ic =
+ (* I/O errors are dealt with at a higher level *)
+ let fp1 = Digest.input ic in
+ let fp2 = Digest.input ic in
+ let headerSize = Marshal.header_size in
+ let header = String.create headerSize in
+ really_input ic header 0 headerSize;
+ if fp1 <> Digest.string header then begin
+ debug (fun () -> Util.msg "bad header checksum\n");
+ raise End_of_file
+ end;
+ let dataSize = Marshal.data_size header 0 in
+ let s = String.create (headerSize + dataSize) in
+ String.blit header 0 s 0 headerSize;
+ really_input ic s headerSize dataSize;
+ if fp2 <> Digest.string s then begin
+ debug (fun () -> Util.msg "bad chunk checksum\n");
+ raise End_of_file
+ end;
+ let q : entry list = Marshal.from_string s 0 in
+ debug (fun () -> Util.msg "read chunk of %d files\n" (List.length q));
+ List.iter (fun (l, p, i) -> PathTbl.add tbl (decompress st l p) i) q
+
+let closeOut st =
+ state := None;
+ try
+ close_out st.oc
+ with Sys_error error ->
+ debug (fun () -> Util.msg "error in closing cache file: %s\n" error)
+
+let write state =
+ let q = Safelist.rev state.queue in
+ let s = Marshal.to_string q [Marshal.No_sharing] in
+ let fp1 = Digest.substring s 0 Marshal.header_size in
+ let fp2 = Digest.string s in
+ begin try
+ Digest.output state.oc fp1; Digest.output state.oc fp2;
+ output_string state.oc s; flush state.oc
+ with Sys_error error ->
+ debug (fun () -> Util.msg "error in writing to cache file: %s\n" error);
+ closeOut state
+ end;
+ state.count <- 0;
+ state.size <- Uutil.Filesize.zero;
+ state.queue <- []
+
+(****)
+
+(* Start and finish dealing with the cache *)
+
+let finish () =
+ PathTbl.clear tbl;
+ match !state with
+ Some st -> if st.queue <> [] then write st;
+ closeOut st
+ | None -> ()
+
+let magic = "Unison fingerprint cache format 1"
+
+let init fastCheck fspath =
+ finish ();
+ if fastCheck then begin
+ begin try
+ let ic = System.open_in_bin fspath in
+ begin try
+ let header = input_line ic in
+ if header <> magic then raise (Sys_error "wrong header");
+ let st = ref "" in
+ while true do read st ic done
+ with
+ Sys_error error ->
+ debug (fun () -> Util.msg "error in loading cache file %s: %s\n"
+ (System.fspathToDebugString fspath) error)
+ | End_of_file ->
+ ()
+ end;
+ begin try
+ close_in ic
+ with Sys_error error ->
+ debug (fun () -> Util.msg "error in closing cache file %s: %s\n"
+ (System.fspathToDebugString fspath) error)
+ end;
+ with Sys_error error ->
+ debug (fun () -> Util.msg "could not open cache file %s: %s\n"
+ (System.fspathToDebugString fspath) error)
+ end;
+ begin try
+ debug (fun () -> Util.msg "opening cache file %s for output\n"
+ (System.fspathToDebugString fspath));
+ let oc =
+ System.open_out_gen
+ [Open_wronly; Open_creat; Open_trunc; Open_binary] 0o600 fspath in
+ output_string oc magic; output_string oc "\n"; flush oc;
+ state :=
+ Some { oc = oc; count = 0; size = Uutil.Filesize.zero;
+ last = ""; queue = [] }
+ with Sys_error error ->
+ debug (fun () -> Util.msg "could not open cache file %s: %s\n"
+ (System.fspathToDebugString fspath) error)
+ end
+ end
+
+(****)
+
+(* Enqueue a fingerprint to be written to disk. *)
+
+let maxCount = 5000
+let maxSize = Uutil.Filesize.ofInt (100 * 1024 * 1024)
+
+let save path res =
+ match !state with
+ None ->
+ ()
+ | Some state ->
+ let (info, _) = res in
+ let l = Props.length info.Fileinfo.desc in
+ state.size <- Uutil.Filesize.add state.size l;
+ state.count <- state.count + 1;
+ let (l, s) = compress state path in
+ state.queue <- (l, s, res) :: state.queue;
+ if state.count > maxCount || state.size > maxSize then write state
+
+(****)
+
+(* Check whether a fingerprint is in the in-memory cache and store it
+ to the on-disk cache in any case. *)
+
+(* HACK: we disable fastcheck for Excel (and MPP) files, as Excel
+ sometimes modifies a file without updating the time stamp. *)
+let excelFile path =
+ let s = Path.toString path in
+ Util.endswith s ".xls"
+ || Util.endswith s ".mpp"
+
+let dataClearlyUnchanged fastCheck path info desc stamp =
+ fastCheck
+ &&
+ Props.same_time info.Fileinfo.desc desc
+ &&
+ Props.length info.Fileinfo.desc = Props.length desc
+ &&
+ not (excelFile path)
+ &&
+ match stamp with
+ Fileinfo.InodeStamp inode ->
+ info.Fileinfo.inode = inode
+ | Fileinfo.CtimeStamp ctime ->
+ (* BCP [Apr 07]: This doesn't work -- ctimes are unreliable
+ under windows. :-(
+ info.Fileinfo.ctime = ctime *)
+ true
+
+let ressClearlyUnchanged fastCheck info ress dataClearlyUnchanged =
+ fastCheck
+ &&
+ Osx.ressUnchanged ress info.Fileinfo.osX.Osx.ressInfo
+ None dataClearlyUnchanged
+
+let clearlyUnchanged fastCheck path newInfo oldInfo =
+ let du =
+ dataClearlyUnchanged fastCheck path newInfo
+ oldInfo.Fileinfo.desc (Fileinfo.stamp oldInfo)
+ in
+ du && ressClearlyUnchanged fastCheck newInfo (Fileinfo.ressStamp oldInfo) du
+
+let fingerprint fastCheck currfspath path info optDig =
+ let res =
+ try
+ let (oldInfo, _) as res = PathTbl.find tbl (Path.toString path) in
+ if not (clearlyUnchanged fastCheck path info oldInfo) then
+ raise Not_found;
+ debug (fun () -> Util.msg "cache hit for path %s\n"
+ (Path.toDebugString path));
+ res
+ with Not_found ->
+ debug (fun () -> Util.msg "cache miss for path %s\n"
+ (Path.toDebugString path));
+ Os.safeFingerprint currfspath path info optDig
+ in
+ save path res;
+ res
Added: trunk/src/fpcache.mli
===================================================================
--- trunk/src/fpcache.mli (rev 0)
+++ trunk/src/fpcache.mli 2010-01-06 21:20:12 UTC (rev 393)
@@ -0,0 +1,20 @@
+(* Unison file synchronizer: src/fpcache.mli *)
+(* Copyright 1999-2010, Benjamin C. Pierce (see COPYING for details) *)
+
+(* Initialize the cache *)
+val init : bool -> System.fspath -> unit
+
+(* Close the cache file and clear the in-memory cache *)
+val finish : unit -> unit
+
+(* Get the fingerprint of a file, possibly from the cache *)
+val fingerprint :
+ bool -> Fspath.t -> Path.local -> Fileinfo.t -> Os.fullfingerprint option ->
+ Fileinfo.t * Os.fullfingerprint
+
+val dataClearlyUnchanged :
+ bool -> Path.local -> Fileinfo.t -> Props.t -> Fileinfo.stamp -> bool
+val ressClearlyUnchanged :
+ bool -> Fileinfo.t -> 'a Osx.ressInfo -> bool -> bool
+(* Is that a file for which fast checking is disabled? *)
+val excelFile : Path.local -> bool
Modified: trunk/src/mkProjectInfo.ml
===================================================================
--- trunk/src/mkProjectInfo.ml 2010-01-05 15:42:43 UTC (rev 392)
+++ trunk/src/mkProjectInfo.ml 2010-01-06 21:20:12 UTC (rev 393)
@@ -65,7 +65,7 @@
Str.matched_group 1 str;;
let extract_int re str = int_of_string (extract_str re str);;
-let revisionString = "$Rev: 388$";;
+let revisionString = "$Rev: 393$";;
let pointVersion = if String.length revisionString > 5
then Scanf.sscanf revisionString "$Rev: %d " (fun x -> x) - pointVersionOrigin
else (* Determining the pointVersionOrigin in bzr is kind of tricky:
@@ -87,7 +87,3 @@
Printf.printf "VERSION=%d.%d.%d\n" majorVersion minorVersion pointVersion;;
Printf.printf "NAME=%s\n" projectName;;
-
-
-
-
Modified: trunk/src/path.ml
===================================================================
--- trunk/src/path.ml 2010-01-05 15:42:43 UTC (rev 392)
+++ trunk/src/path.ml 2010-01-06 21:20:12 UTC (rev 393)
@@ -192,6 +192,7 @@
(* No need to perform case normalization on local paths *)
let hash p = Hashtbl.hash p
+let equal (p1 : local) (p2 : local) = p1 = p2
(* Pref controlling whether symlinks are followed. *)
let followPred = Pred.create "follow"
Modified: trunk/src/path.mli
===================================================================
--- trunk/src/path.mli 2010-01-05 15:42:43 UTC (rev 392)
+++ trunk/src/path.mli 2010-01-06 21:20:12 UTC (rev 393)
@@ -31,6 +31,7 @@
val addPrefixToFinalName : local -> string -> local
val compare : t -> t -> int
+val equal : local -> local -> bool
val hash : local -> int
val followLink : local -> bool
Modified: trunk/src/update.ml
===================================================================
--- trunk/src/update.ml 2010-01-05 15:42:43 UTC (rev 392)
+++ trunk/src/update.ml 2010-01-06 21:20:12 UTC (rev 393)
@@ -165,7 +165,7 @@
(* ----- *)
(* The status of an archive *)
-type archiveVersion = MainArch | NewArch | ScratchArch | Lock
+type archiveVersion = MainArch | NewArch | ScratchArch | Lock | FPCache
let showArchiveName =
Prefs.createBool "showarchive" false
@@ -201,7 +201,8 @@
let archiveName fspath (v: archiveVersion): string * string =
let n = archiveHash fspath in
let temp = match v with
- MainArch -> "ar" | NewArch -> "tm" | ScratchArch -> "sc" | Lock -> "lk"
+ MainArch -> "ar" | NewArch -> "tm" | ScratchArch -> "sc"
+ | Lock -> "lk" | FPCache -> "fp"
in
(Printf.sprintf "%s%s" temp n,
thisRootsGlobalName fspath)
@@ -1191,13 +1192,6 @@
oldInfoOf archive)
end
-(* HACK: we disable fastcheck for Excel (and MPP) files on Windows, as Excel
- sometimes modifies a file without updating the time stamp. *)
-let excelFile path =
- let s = Path.toString path in
- Util.endswith s ".xls"
- || Util.endswith s ".mpp"
-
(* Check whether a file has changed has changed, by comparing its digest and
properties against [archDesc], [archDig], and [archStamp].
Returns a pair (optArch, ui) where [optArch] is *not* None when the file remains
@@ -1226,27 +1220,10 @@
(Uutil.Filesize.toString (Props.length info.Fileinfo.desc));
Util.msg "\n");
let dataClearlyUnchanged =
- fastCheck
- &&
- Props.same_time info.Fileinfo.desc archDesc
- &&
- Props.length info.Fileinfo.desc = Props.length archDesc
- &&
- not (excelFile path)
- &&
- match archStamp with
- Fileinfo.InodeStamp inode ->
- info.Fileinfo.inode = inode
- | Fileinfo.CtimeStamp ctime ->
- (* BCP [Apr 07]: This doesn't work -- ctimes are unreliable
- under windows. :-(
- info.Fileinfo.ctime = ctime *)
- true in
+ Fpcache.dataClearlyUnchanged fastCheck path info archDesc archStamp in
let ressClearlyUnchanged =
- fastCheck
- &&
- Osx.ressUnchanged archRess info.Fileinfo.osX.Osx.ressInfo
- None dataClearlyUnchanged in
+ Fpcache.ressClearlyUnchanged fastCheck info archRess dataClearlyUnchanged
+ in
if dataClearlyUnchanged && ressClearlyUnchanged then begin
Xferhint.insertEntry currfspath path archDig;
None, checkPropChange info archive archDesc
@@ -1254,7 +1231,7 @@
debugverbose (fun() -> Util.msg " Double-check possibly updated file\n");
showStatusAddLength info;
let (info, newDigest) =
- Os.safeFingerprint currfspath path info
+ Fpcache.fingerprint fastCheck currfspath path info
(if dataClearlyUnchanged then Some archDig else None) in
Xferhint.insertEntry currfspath path newDigest;
debug (fun() -> Util.msg " archive digest = %s current digest = %s\n"
@@ -1492,7 +1469,9 @@
None,
begin
showStatusAddLength info;
- let (info, dig) = Os.safeFingerprint currfspath path info None in
+ let (info, dig) =
+ Fpcache.fingerprint
+ fastCheckInfos.fastCheck currfspath path info None in
Xferhint.insertEntry currfspath path dig;
Updates (File (info.Fileinfo.desc,
ContentsUpdated (dig, Fileinfo.stamp info,
@@ -1582,8 +1561,12 @@
dirFastCheck = useFastChecking () && Util.osType = `Unix;
dirStamp = dirStamp }
in
+ let (cacheFilename, _) = archiveName fspath FPCache in
+ let cacheFile = Os.fileInUnisonDir cacheFilename in
+ Fpcache.init fastCheckInfos.fastCheck cacheFile;
let (arch, ui) =
buildUpdateRec archive fspath here fastCheckInfos in
+ Fpcache.finish ();
(begin match arch with
None -> archive
| Some arch -> arch
@@ -2067,7 +2050,7 @@
&&
Props.length desc = Props.length oldDesc
&&
- not (excelFile path)
+ not (Fpcache.excelFile path)
&&
Osx.ressUnchanged oldRess ress None true
Modified: trunk/src/update.mli
===================================================================
--- trunk/src/update.mli 2010-01-05 15:42:43 UTC (rev 392)
+++ trunk/src/update.mli 2010-01-06 21:20:12 UTC (rev 393)
@@ -64,9 +64,6 @@
(* Are we checking fast, or carefully? *)
val useFastChecking : unit -> bool
-(* Is that a file for which fast checking is disabled? *)
-val excelFile : Path.local -> bool
-
(* Print the archive to the current formatter (see Format) *)
val showArchive: archive -> unit
More information about the Unison-hackers
mailing list