Implement beginning of cycle testing
authorAndrew Young <youngar17@gmail.com>
Mon, 13 Aug 2012 14:49:55 +0000 (10:49 -0400)
committerAndrew Young <youngar17@gmail.com>
Mon, 13 Aug 2012 14:49:55 +0000 (10:49 -0400)
- In progress solution to heading movements causing cycles in the
  document graph.

src/doc_ref.c
src/doc_ref.h

index 35b64d5..247def9 100644 (file)
@@ -83,7 +83,8 @@ static int  is_related  (struct context *ctxt, OFFSET xoff, OFFSET yoff);
   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)
@@ -114,13 +115,13 @@ is_related (struct context *ctxt, OFFSET xoff, OFFSET 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,
@@ -148,6 +149,7 @@ doc_reflist_merge (gl_list_t ancestor, gl_list_t descendant, merge_ctxt *merge_c
   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;
@@ -231,10 +233,16 @@ doc_reflist_merge (gl_list_t ancestor, gl_list_t descendant, merge_ctxt *merge_c
       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);
 
@@ -246,8 +254,8 @@ doc_reflist_merge (gl_list_t ancestor, gl_list_t descendant, merge_ctxt *merge_c
       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);
@@ -270,8 +278,9 @@ doc_reflist_merge (gl_list_t ancestor, gl_list_t descendant, merge_ctxt *merge_c
          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++;
        }
index 158d558..763c6cb 100644 (file)
@@ -14,6 +14,7 @@
 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
@@ -34,6 +35,8 @@ typedef struct doc_ref
 {
   doc_src src;
   doc_elt *elt;
+  doc_ref *parent;
+  bool circular_conflict;
 } doc_ref;
 
 /* Constructor and destructor */
@@ -50,6 +53,14 @@ static inline void doc_ref_set_src (doc_ref *ref, doc_src src);
 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
@@ -65,7 +76,7 @@ bool doc_reflist_isupdated (gl_list_t 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
@@ -82,6 +93,8 @@ doc_ref_create_empty ()
   doc_ref *d = malloc (sizeof (doc_ref));
   d->elt = NULL;
   d->src = 0;
+  d->parent = NULL;
+  d->circular_conflict = false;
   return d;
 }
 
@@ -136,4 +149,69 @@ doc_ref_contains (doc_ref *ref, doc_src src)
   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 */