aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd_linux.go21
-rw-r--r--cmd_windows.go42
2 files changed, 51 insertions, 12 deletions
diff --git a/cmd_linux.go b/cmd_linux.go
index 4fcc891..b80b197 100644
--- a/cmd_linux.go
+++ b/cmd_linux.go
@@ -88,7 +88,7 @@ func handleClient(conn net.Conn, stack *GitignoreStack) {
defer conn.Close()
scanner := bufio.NewScanner(conn)
- scanner.Buffer(make([]byte, 0, 64*1024*1024), 64*1024*1024) // 64MB buffer for large manifests
+ scanner.Buffer(make([]byte, 0, 1024*1024), 1024*1024) // 1MB buffer per batch
remoteManifest := &Manifest{Files: make(map[string]FileMeta)}
for scanner.Scan() {
@@ -99,11 +99,19 @@ func handleClient(conn net.Conn, stack *GitignoreStack) {
}
switch msg.Type {
- case "manifest":
- remoteManifest = ManifestFromJSON(msg.Files)
- logInfo("manifest: received %d files from host", len(remoteManifest.Files))
+ case "manifest_batch":
+ for k, v := range msg.Files {
+ remoteManifest.Files[k] = FileMeta{
+ Size: v.Size,
+ Mode: os.FileMode(v.Mode),
+ ModTime: parseTime(v.ModTime),
+ Symlink: v.Symlink,
+ }
+ }
+ logDebug("manifest: received batch (%d files, total: %d)", len(msg.Files), len(remoteManifest.Files))
case "manifest_done":
+ logInfo("manifest: received %d files from host", len(remoteManifest.Files))
logInfo("manifest: comparing with local state ...")
syncFromManifest(remoteManifest, stack)
logInfo("sync: done")
@@ -276,3 +284,8 @@ func scanLocalDirectory(root string) *Manifest {
return manifest
}
+
+func parseTime(s string) time.Time {
+ t, _ := time.Parse(time.RFC3339Nano, s)
+ return t
+}
diff --git a/cmd_windows.go b/cmd_windows.go
index 7df0a9b..dfe137a 100644
--- a/cmd_windows.go
+++ b/cmd_windows.go
@@ -275,16 +275,42 @@ func scanDirectory(root string, stack *GitignoreStack) *Manifest {
}
func sendManifest(conn net.Conn, manifest *Manifest) {
- msg := &ProtocolMessage{
- Type: "manifest",
- Files: manifest.ToJSON(),
+ const batchSize = 1000
+ files := make([]FileMetaJSON, 0, batchSize)
+ paths := make([]string, 0, batchSize)
+
+ for path, meta := range manifest.ToJSON() {
+ paths = append(paths, path)
+ files = append(files, meta)
+
+ if len(files) >= batchSize {
+ msg := &ProtocolMessage{
+ Type: "manifest_batch",
+ Files: make(map[string]FileMetaJSON),
+ }
+ for i, p := range paths {
+ msg.Files[p] = files[i]
+ }
+ data, _ := EncodeMessage(msg)
+ data = append(data, '\n')
+ conn.Write(data)
+ files = files[:0]
+ paths = paths[:0]
+ }
}
- data, err := EncodeMessage(msg)
- if err != nil {
- return
+
+ if len(files) > 0 {
+ msg := &ProtocolMessage{
+ Type: "manifest_batch",
+ Files: make(map[string]FileMetaJSON),
+ }
+ for i, p := range paths {
+ msg.Files[p] = files[i]
+ }
+ data, _ := EncodeMessage(msg)
+ data = append(data, '\n')
+ conn.Write(data)
}
- data = append(data, '\n')
- conn.Write(data)
done := &ProtocolMessage{Type: "manifest_done"}
doneData, _ := EncodeMessage(done)