Replace TREE_WALK_FILE with csync_file_stat_t
authorJocelyn Turcotte <jturcotte@woboq.com>
Thu, 17 Aug 2017 12:39:23 +0000 (14:39 +0200)
committerRoeland Jago Douma <roeland@famdouma.nl>
Thu, 5 Oct 2017 20:01:04 +0000 (22:01 +0200)
Just expose csync_file_stat_t since we don't need an abstraction layer
anymore. Also pass the nodes of both trees directly to the visitor
function.

Issue #1817

src/csync/csync.cpp
src/csync/csync.h
src/libsync/syncengine.cpp
src/libsync/syncengine.h

index eefc8904ef5edc2dc76254bd7f827e06a2714e6c..aa531e18bc5e5a9dcd2399274caedcd571d2f5fa 100644 (file)
@@ -279,9 +279,8 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
     int rc = 0;
     csync_file_stat_t *cur         = NULL;
     CSYNC *ctx                     = NULL;
-    c_rbtree_visit_func *visitor   = NULL;
+    csync_treewalk_visit_func *visitor   = NULL;
     _csync_treewalk_context *twctx = NULL;
-    TREE_WALK_FILE trav;
     c_rbtree_t *other_tree = NULL;
     c_rbnode_t *other_node = NULL;
 
@@ -334,6 +333,8 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
         SAFE_FREE(renamed_path);
     }
 
+    csync_file_stat_t *other = other_node ? (csync_file_stat_t*)other_node->data : NULL;
+
     if (obj == NULL || data == NULL) {
       ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
       return -1;
@@ -351,45 +352,9 @@ static int _csync_treewalk_visitor(void *obj, void *data) {
         return 0;
     }
 
-    visitor = (c_rbtree_visit_func*)(twctx->user_visitor);
+    visitor = (csync_treewalk_visit_func*)(twctx->user_visitor);
     if (visitor != NULL) {
-      trav.path         = cur->path;
-      trav.size         = cur->size;
-      trav.modtime      = cur->modtime;
-      trav.type         = cur->type;
-      trav.instruction  = cur->instruction;
-      trav.rename_path  = cur->rename_path;
-      trav.etag         = cur->etag;
-      trav.file_id      = cur->file_id;
-      trav.remotePerm = cur->remotePerm;
-      trav.directDownloadUrl = cur->directDownloadUrl.data();
-      trav.directDownloadCookies = cur->directDownloadCookies.data();
-      trav.inode        = cur->inode;
-
-      trav.error_status = cur->error_status;
-      trav.has_ignored_files = cur->has_ignored_files;
-      trav.checksumHeader = cur->checksumHeader;
-
-      if( other_node ) {
-          csync_file_stat_t *other_stat = (csync_file_stat_t*)other_node->data;
-          trav.other.etag = other_stat->etag;
-          trav.other.file_id = other_stat->file_id;
-          trav.other.instruction = other_stat->instruction;
-          trav.other.modtime = other_stat->modtime;
-          trav.other.size = other_stat->size;
-      } else {
-          trav.other.etag = 0;
-          trav.other.file_id = 0;
-          trav.other.instruction = CSYNC_INSTRUCTION_NONE;
-          trav.other.modtime = 0;
-          trav.other.size = 0;
-      }
-
-      rc = (*visitor)(&trav, twctx->userdata);
-      cur->instruction = trav.instruction;
-      if (trav.etag != cur->etag) { // FIXME It would be nice to have this documented
-          cur->etag = trav.etag;
-      }
+      rc = (*visitor)(cur, other, twctx->userdata);
 
       return rc;
     }
index 1cf16f937172d9ed9a0707d37dab8906acec7bef..b8d882ab872e712732fbecfe680759600d1ae855 100644 (file)
@@ -195,47 +195,6 @@ struct csync_file_stat_s {
   { }
 };
 
-/**
- * CSync File Traversal structure.
- *
- * This structure is passed to the visitor function for every file
- * which is seen.
- *
- */
-
-struct csync_tree_walk_file_s {
-    const char *path;
-    int64_t     size;
-    int64_t     inode;
-    time_t      modtime;
-    mode_t      mode;
-    enum csync_ftw_type_e     type;
-    enum csync_instructions_e instruction;
-
-    /* For directories: Does it have children that were ignored (hidden or ignore pattern) */
-    int         has_ignored_files;
-
-    const char *rename_path;
-    const char *etag;
-    const char *file_id;
-    const char *remotePerm;
-    char *directDownloadUrl;
-    char *directDownloadCookies;
-
-    const char *checksumHeader;
-
-    struct {
-        int64_t     size;
-        time_t      modtime;
-        const char *etag;
-        const char *file_id;
-        enum csync_instructions_e instruction;
-    } other;
-
-    CSYNC_STATUS error_status;
-};
-typedef struct csync_tree_walk_file_s TREE_WALK_FILE;
-
 /**
  * csync handle
  */
@@ -402,7 +361,7 @@ CSYNC_STATUS OCSYNC_EXPORT csync_get_status(CSYNC *ctx);
 /* Used for special modes or debugging */
 int OCSYNC_EXPORT csync_set_status(CSYNC *ctx, int status);
 
-typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
+typedef int csync_treewalk_visit_func(csync_file_stat_t *cur, csync_file_stat_t *other, void*);
 
 /**
  * @brief Walk the local file tree and call a visitor function for each file.
index df0f2e0e82a560123a752054919d8faaa38d3750..dac3cde37c90b2047d389e912cd71f5c0196a8d1 100644 (file)
@@ -334,14 +334,14 @@ void SyncEngine::deleteStaleErrorBlacklistEntries(const SyncFileItemVector &sync
     _journal->deleteStaleErrorBlacklistEntries(blacklist_file_paths);
 }
 
-int SyncEngine::treewalkLocal(TREE_WALK_FILE *file, void *data)
+int SyncEngine::treewalkLocal(csync_file_stat_t *file, csync_file_stat_t *other, void *data)
 {
-    return static_cast<SyncEngine *>(data)->treewalkFile(file, false);
+    return static_cast<SyncEngine *>(data)->treewalkFile(file, other, false);
 }
 
-int SyncEngine::treewalkRemote(TREE_WALK_FILE *file, void *data)
+int SyncEngine::treewalkRemote(csync_file_stat_t *file, csync_file_stat_t *other, void *data)
 {
-    return static_cast<SyncEngine *>(data)->treewalkFile(file, true);
+    return static_cast<SyncEngine *>(data)->treewalkFile(file, other, true);
 }
 
 /**
@@ -354,7 +354,7 @@ int SyncEngine::treewalkRemote(TREE_WALK_FILE *file, void *data)
  *
  * See doc/dev/sync-algorithm.md for an overview.
  */
-int SyncEngine::treewalkFile(TREE_WALK_FILE *file, bool remote)
+int SyncEngine::treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other, bool remote)
 {
     if (!file)
         return -1;
@@ -407,17 +407,17 @@ int SyncEngine::treewalkFile(TREE_WALK_FILE *file, bool remote)
         }
     }
 
-    if (file->file_id && file->file_id[0]) {
+    if (!file->file_id.isEmpty()) {
         item->_fileId = file->file_id;
     }
-    if (file->directDownloadUrl) {
+    if (!file->directDownloadUrl.isEmpty()) {
         item->_directDownloadUrl = QString::fromUtf8(file->directDownloadUrl);
     }
-    if (file->directDownloadCookies) {
+    if (!file->directDownloadCookies.isEmpty()) {
         item->_directDownloadCookies = QString::fromUtf8(file->directDownloadCookies);
     }
-    if (file->remotePerm && file->remotePerm[0]) {
-        item->_remotePerm = QByteArray(file->remotePerm);
+    if (!file->remotePerm.isEmpty()) {
+        item->_remotePerm = file->remotePerm;
         if (remote)
             _remotePerms[item->_file] = item->_remotePerm;
     }
@@ -438,12 +438,12 @@ int SyncEngine::treewalkFile(TREE_WALK_FILE *file, bool remote)
     }
 
     // Sometimes the discovery computes checksums for local files
-    if (!remote && file->checksumHeader) {
-        item->_checksumHeader = QByteArray(file->checksumHeader);
+    if (!remote && !file->checksumHeader.isEmpty()) {
+        item->_checksumHeader = file->checksumHeader;
     }
     // For conflicts, store the remote checksum there
-    if (remote && item->_instruction == CSYNC_INSTRUCTION_CONFLICT && file->checksumHeader) {
-        item->_checksumHeader = QByteArray(file->checksumHeader);
+    if (remote && item->_instruction == CSYNC_INSTRUCTION_CONFLICT && !file->checksumHeader.isEmpty()) {
+        item->_checksumHeader = file->checksumHeader;
     }
 
     // record the seen files to be able to clean the journal later
@@ -533,7 +533,7 @@ int SyncEngine::treewalkFile(TREE_WALK_FILE *file, bool remote)
 
     bool isDirectory = file->type == CSYNC_FTW_TYPE_DIR;
 
-    if (file->etag && file->etag[0]) {
+    if (!file->etag.isEmpty()) {
         item->_etag = file->etag;
     }
 
@@ -562,7 +562,7 @@ int SyncEngine::treewalkFile(TREE_WALK_FILE *file, bool remote)
     switch (file->instruction) {
     case CSYNC_INSTRUCTION_NONE: {
         // Any files that are instruction NONE?
-        if (!isDirectory && file->other.instruction == CSYNC_INSTRUCTION_NONE) {
+        if (!isDirectory && (!other || other->instruction == CSYNC_INSTRUCTION_NONE)) {
             _hasNoneFiles = true;
         }
         // No syncing or update to be done.
@@ -592,11 +592,13 @@ int SyncEngine::treewalkFile(TREE_WALK_FILE *file, bool remote)
             if (remote) {
                 QString filePath = _localPath + item->_file;
 
-                // Even if the mtime is different on the server, we always want to keep the mtime from
-                // the file system in the DB, this is to avoid spurious upload on the next sync
-                item->_modtime = file->other.modtime;
-                // same for the size
-                item->_size = file->other.size;
+                if (other) {
+                    // Even if the mtime is different on the server, we always want to keep the mtime from
+                    // the file system in the DB, this is to avoid spurious upload on the next sync
+                    item->_modtime = other->modtime;
+                    // same for the size
+                    item->_size = other->size;                    
+                }
 
                 // If the 'W' remote permission changed, update the local filesystem
                 SyncJournalFileRecord prev = _journal->getFileRecord(item->_file);
@@ -638,7 +640,7 @@ int SyncEngine::treewalkFile(TREE_WALK_FILE *file, bool remote)
             // This counts as a NONE for detecting if all the files on the server were changed
             _hasNoneFiles = true;
         } else if (!isDirectory) {
-            auto difftime = std::difftime(file->modtime, file->other.modtime);
+            auto difftime = std::difftime(file->modtime, other ? other->modtime : 0);
             if (difftime < -3600 * 2) {
                 // We are going back on time
                 // We only increment if the difference is more than two hours to avoid clock skew
@@ -672,11 +674,13 @@ int SyncEngine::treewalkFile(TREE_WALK_FILE *file, bool remote)
 
     _needsUpdate = true;
 
-    item->log._other_etag = file->other.etag;
-    item->log._other_fileId = file->other.file_id;
-    item->log._other_instruction = file->other.instruction;
-    item->log._other_modtime = file->other.modtime;
-    item->log._other_size = file->other.size;
+    if (other) {
+        item->log._other_etag = other->etag;
+        item->log._other_fileId = other->file_id;
+        item->log._other_instruction = other->instruction;
+        item->log._other_modtime = other->modtime;
+        item->log._other_size = other->size;        
+    }
 
     _syncItemMap.insert(key, item);
 
index 50e52f6f4477e4d388dac324ace9d126c6091e8a..ec4d6712ff84dbb25a7959fc5e42f4da1690be53 100644 (file)
@@ -170,9 +170,9 @@ private:
 
     QString journalDbFilePath() const;
 
-    static int treewalkLocal(TREE_WALK_FILE *, void *);
-    static int treewalkRemote(TREE_WALK_FILE *, void *);
-    int treewalkFile(TREE_WALK_FILE *, bool);
+    static int treewalkLocal(csync_file_stat_t *file, csync_file_stat_t *other, void *);
+    static int treewalkRemote(csync_file_stat_t *file, csync_file_stat_t *other, void *);
+    int treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other, bool);
     bool checkErrorBlacklisting(SyncFileItem &item);
 
     // Cleans up unnecessary downloadinfo entries in the journal as well