mirror of
https://github.com/nextcloud/desktop.git
synced 2025-10-26 11:17:43 +00:00
Implement the reconciler.
This commit is contained in:
parent
49543390e2
commit
4489fbfa2b
@ -160,10 +160,15 @@ int main(int argc, char **argv) {
|
||||
printf("Version: %s\n", csync_version());
|
||||
|
||||
if (arguments.update) {
|
||||
csync_update(csync);
|
||||
if (csync_update(csync) < 0) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.reconcile) {
|
||||
if (csync_reconcile(csync) < 0) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.propagate) {
|
||||
@ -176,5 +181,10 @@ int main(int argc, char **argv) {
|
||||
csync_destroy(csync);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
perror("csync");
|
||||
csync_destroy(csync);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -41,6 +41,7 @@ set(csync_SRCS
|
||||
csync_exclude.c
|
||||
csync_journal.c
|
||||
csync_lock.c
|
||||
csync_reconcile.c
|
||||
csync_time.c
|
||||
csync_util.c
|
||||
csync_update.c
|
||||
|
||||
49
src/csync.c
49
src/csync.c
@ -38,6 +38,7 @@
|
||||
#include "csync_util.h"
|
||||
|
||||
#include "csync_update.h"
|
||||
#include "csync_reconcile.h"
|
||||
|
||||
#include "vio/csync_vio.h"
|
||||
|
||||
@ -48,7 +49,7 @@ static int key_cmp(const void *key, const void *data) {
|
||||
uint64_t a;
|
||||
csync_file_stat_t *b;
|
||||
|
||||
a = POINTER_TO_INT(key);
|
||||
a = (uint64_t) key;
|
||||
b = (csync_file_stat_t *) data;
|
||||
|
||||
if (a < b->phash) {
|
||||
@ -334,6 +335,52 @@ int csync_update(CSYNC *ctx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int csync_reconcile(CSYNC *ctx) {
|
||||
int rc = -1;
|
||||
time_t start, finish;
|
||||
|
||||
if (ctx == NULL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Reconciliation for local replica */
|
||||
time(&start);
|
||||
ctx->current = LOCAL_REPLICA;
|
||||
ctx->replica = ctx->local.type;
|
||||
|
||||
rc = csync_reconcile_updates(ctx);
|
||||
|
||||
time(&finish);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"Reconciliation for local replica took %.2f seconds",
|
||||
difftime(finish, start));
|
||||
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Reconciliation for local replica */
|
||||
time(&start);
|
||||
ctx->current = REMOTE_REPLCIA;
|
||||
ctx->replica = ctx->remote.type;
|
||||
|
||||
rc = csync_reconcile_updates(ctx);
|
||||
|
||||
time(&finish);
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG,
|
||||
"Reconciliation for local replica took %.2f seconds",
|
||||
difftime(finish, start));
|
||||
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->status |= CSYNC_RECONCILE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tree_destructor(void *data) {
|
||||
csync_file_stat_t *freedata = NULL;
|
||||
|
||||
|
||||
133
src/csync_reconcile.c
Normal file
133
src/csync_reconcile.c
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2008 by Andreas Schneider <mail@cynapses.org>
|
||||
*
|
||||
* 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 2
|
||||
* 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, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* vim: ts=2 sw=2 et cindent
|
||||
*/
|
||||
|
||||
#include "csync_private.h"
|
||||
#include "csync_reconcile.h"
|
||||
#include "csync_util.h"
|
||||
|
||||
#define CSYNC_LOG_CATEGORY_NAME "csync.reconciler"
|
||||
#include "csync_log.h"
|
||||
|
||||
static int csync_merge_algorithm_visitor(void *obj, void *data) {
|
||||
csync_file_stat_t *cur = NULL;
|
||||
csync_file_stat_t *other = NULL;
|
||||
CSYNC *ctx = NULL;
|
||||
c_rbtree_t *tree = NULL;
|
||||
c_rbnode_t *node = NULL;
|
||||
|
||||
cur = (csync_file_stat_t *) obj;
|
||||
ctx = (CSYNC *) data;
|
||||
|
||||
/* we need the opposite tree! */
|
||||
switch (ctx->current) {
|
||||
case LOCAL_REPLICA:
|
||||
tree = ctx->remote.tree;
|
||||
break;
|
||||
case REMOTE_REPLCIA:
|
||||
tree = ctx->local.tree;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
node = c_rbtree_find(tree, (void *) cur->phash);
|
||||
/* file only found on current replica */
|
||||
if (node == NULL) {
|
||||
switch(cur->instruction) {
|
||||
/* file has been modified */
|
||||
case CSYNC_INSTRUCTION_EVAL:
|
||||
cur->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
break;
|
||||
/* file has been removed on the opposite replica */
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
cur->instruction = CSYNC_INSTRUCTION_REMOVE;
|
||||
break;
|
||||
case CSYNC_INSTRUCTION_RENAME:
|
||||
cur->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* file found on the other replica
|
||||
*/
|
||||
other = (csync_file_stat_t *) node->data;
|
||||
|
||||
switch (cur->instruction) {
|
||||
/* file on current replica is new */
|
||||
case CSYNC_INSTRUCTION_NEW:
|
||||
/* file on current replica has been modified */
|
||||
case CSYNC_INSTRUCTION_EVAL:
|
||||
switch (other->instruction) {
|
||||
/* file on other replica is new too */
|
||||
case CSYNC_INSTRUCTION_NEW:
|
||||
if (cur->modtime > other->modtime) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
}
|
||||
cur->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
break;
|
||||
/* file on other replica has changed too */
|
||||
case CSYNC_INSTRUCTION_EVAL:
|
||||
/* file on current replica is newer */
|
||||
if (cur->modtime > other->modtime) {
|
||||
cur->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
}
|
||||
/* file on opposite replica is newer */
|
||||
cur->instruction = CSYNC_INSTRUCTION_REMOVE;
|
||||
break;
|
||||
/* file on the other replica has not been modified */
|
||||
case CSYNC_INSTRUCTION_NONE:
|
||||
cur->instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s, instruction: %s", cur->path, csync_instruction_str(cur->instruction));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int csync_reconcile_updates(CSYNC *ctx) {
|
||||
int rc = -1;
|
||||
c_rbtree_t *tree = NULL;
|
||||
|
||||
switch (ctx->current) {
|
||||
case LOCAL_REPLICA:
|
||||
tree = ctx->local.tree;
|
||||
break;
|
||||
case REMOTE_REPLCIA:
|
||||
tree = ctx->remote.tree;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rc = c_rbtree_walk(tree, (void *) ctx, csync_merge_algorithm_visitor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
28
src/csync_reconcile.h
Normal file
28
src/csync_reconcile.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* libcsync -- a library to sync a directory with another
|
||||
*
|
||||
* Copyright (c) 2008 by Andreas Schneider <mail@cynapses.org>
|
||||
*
|
||||
* 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 2
|
||||
* 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, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* vim: ft=c.doxygen ts=2 sw=2 et cindent
|
||||
*/
|
||||
|
||||
#ifndef _CSYNC_RECONCILE_H
|
||||
#define _CSYNC_RECONCILE_H
|
||||
|
||||
int csync_reconcile_updates(CSYNC *ctx);
|
||||
|
||||
#endif /* _CSYNC_RECONCILE_H */
|
||||
Loading…
Reference in New Issue
Block a user