mapped_state *a_state; \
mapped_state *d_state; \
gl_list_t ancestor; \
- gl_list_t descendant;
+ gl_list_t descendant; \
+ merge_ctxt *merge_ctxt;
#define NOTE_DELETE(ctxt, xoff) note_delete (ctxt, xoff)
#define NOTE_INSERT(ctxt, yoff) note_insert (ctxt, yoff)
doc_ref *a_ref = (doc_ref * )gl_list_get_at (ctxt->ancestor, xoff);
doc_ref *d_ref = (doc_ref *)gl_list_get_at (ctxt->descendant, yoff);
- int result = doc_elt_isrelated (a_ref, d_ref, NULL);
+ int result = doc_elt_isrelated (a_ref, d_ref, ctxt->merge_ctxt);
debug_msg (MERGE, 4, "comparing (%d, %d)=%d\n", xoff, yoff, result);
return result;
}
void
-doc_reflist_merge (gl_list_t ancestor, gl_list_t descendant, merge_ctxt *merge_ctxt)
+doc_reflist_merge (doc_ref *parent, gl_list_t ancestor, gl_list_t descendant, merge_ctxt *merge_ctxt)
{
/* First, create a mapped_state for every element that will be mapped.
* Compare the two strigs marking mapped and unmapped nodes. Then,
ctxt.a_state = a_state;
ctxt.ancestor = ancestor;
ctxt.descendant = descendant;
+ ctxt.merge_ctxt = merge_ctxt;
/* Allocate data for the algorithm to use*/
size_t diags = a_size + d_size + 3;
if (next == 1)
{
/* Insert an unmatched node */
- debug_msg (MERGE, 3, "Inserting node\n");
+ debug_msg (MERGE, 3, "Inserting node d_index=%d\n", d_index);
doc_ref * d_ref = (doc_ref *) gl_list_get_at (descendant, d_index);
gl_list_nx_add_at (ancestor, a_index, (void *) d_ref);
+ /* check for a circular conflict */
+ //doc_ref_set_parent (d_ref, parent);
+
+ /* this next line should not be necessary */
+ //doc_ref_check_for_circular_conflict (d_ref);
+
//mark_insert_children ();
doc_elt_note_insert (d_ref, merge_ctxt);
else if (next == 2)
{
/* Delete an unmatched node */
- debug_msg (MERGE, 3, "Removing node\n");
- doc_ref * a_ref = (doc_ref *) gl_list_get_at (ancestor, d_index);
+ debug_msg (MERGE, 3, "Removing node a_index=%d\n", a_index);
+ doc_ref * a_ref = (doc_ref *) gl_list_get_at (ancestor, a_index);
// mark_remove_children (m_child, src);
doc_elt_note_delete (a_ref, merge_ctxt);
doc_elt_merge (a_ref, d_ref, merge_ctxt);
/* make the doc_refs point to the same element */
- doc_ref_set_elt (d_ref, doc_ref_get_elt (a_ref) );
-
+ //doc_ref_set_elt (d_ref, doc_ref_get_elt (a_ref) );
+ //doc_ref_set_parent (d_ref, doc_ref_get_parent (a_ref));
+ //printf ("merging docrefs, par=%d, ref=%d\n", doc_ref_get_elt (a_ref), doc_ref_get_elt (d_ref));
a_index++;
d_index++;
}
struct doc_elt;
typedef struct doc_elt doc_elt;
typedef struct merge_ctxt merge_ctxt;
+typedef struct doc_ref doc_ref;
/**
* Indicates an input document (ancestor, local, or source). Used to
{
doc_src src;
doc_elt *elt;
+ doc_ref *parent;
+ bool circular_conflict;
} doc_ref;
/* Constructor and destructor */
static inline void doc_ref_add_src (doc_ref *ref, doc_src src);
static inline bool doc_ref_isexactly (doc_ref *ref, doc_src src);
static inline bool doc_ref_contains (doc_ref *ref, doc_src src);
+static inline doc_ref *doc_ref_get_parent (doc_ref *ref);
+static inline void doc_ref_set_paraent (doc_ref *ref, doc_ref* parent);
+
+/* circular conflict */
+static inline bool doc_ref_is_circular_conflict (doc_ref *ref);
+static inline void doc_ref_set_circular_conflict (doc_ref *ref, bool conflict);
+/* check for a circulor conflic, and mark it in all doc_refs */
+static inline bool dec_ref_check_for_circular_conflict (doc_ref *ref);
/*
* doc_reflist
/**
* @brief Merge two doc_ref lists together. This function changes ancestor.
*/
-void doc_reflist_merge (gl_list_t ancestor, gl_list_t descendant, merge_ctxt *ctxt);
+void doc_reflist_merge (doc_ref *parent, gl_list_t ancestor, gl_list_t descendant, merge_ctxt *ctxt);
/**
* @brief print a list of ref_docs
doc_ref *d = malloc (sizeof (doc_ref));
d->elt = NULL;
d->src = 0;
+ d->parent = NULL;
+ d->circular_conflict = false;
return d;
}
return (ref->src & src);
}
+
+static inline doc_ref *doc_ref_get_parent (doc_ref *ref)
+{
+ return ref->parent;
+}
+
+static inline void doc_ref_set_parent (doc_ref *ref, doc_ref* parent)
+{
+ ref->parent = parent;
+ return;
+}
+
+static inline bool doc_ref_is_circular_conflict (doc_ref *ref)
+{
+ return ref->circular_conflict;
+}
+
+static inline void doc_ref_set_circular_conflict (doc_ref *ref, bool conflict)
+{
+ ref->circular_conflict = conflict;
+}
+
+/* check for a circulor conflict, and mark it in all doc_refs */
+static inline bool doc_ref_check_for_circular_conflict (doc_ref *ref)
+{
+ bool exit = false;
+ bool conflict = false;
+
+ doc_ref *parent = doc_ref_get_parent (ref);
+
+ while ((parent != NULL)
+ && (!conflict)
+ && !(doc_ref_is_circular_conflict(parent)))
+ {
+ printf ("checking parent par=%d, ref=%d\n",
+ doc_ref_get_elt (parent), doc_ref_get_elt (ref));
+
+ if (doc_ref_get_elt (parent) == doc_ref_get_elt (ref))
+ {
+ printf ("CIRCULAR CONFLICT\n");
+ conflict = true;
+ }
+ parent = doc_ref_get_parent ( parent );
+ }
+
+ /* set the doc_refs as having a conflict, if there was one */
+ exit = false;
+ if (conflict)
+ {
+ doc_ref * parent = doc_ref_get_parent (ref);
+ while ( (parent != NULL) && (!exit))
+ {
+ if (doc_ref_get_elt (parent) == doc_ref_get_elt (ref))
+ {
+ exit = true;
+ }
+ doc_ref_set_circular_conflict (parent, true);
+ parent = doc_ref_get_parent (parent);
+ }
+ }
+
+ printf ("conflict = %d\n", conflict);
+ return conflict;
+}
+
#endif /* DOC_REF_H */