From e06bb27be4fd16ea12bdcb6fdbee06de85cd1dd0 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 2 Jan 2015 12:25:55 +0100 Subject: [PATCH] stub complete implementation framework for diff detection without implementation; but it is clear now where snapshots are taken and how the implementation will be hooked up: as iterator based on a state core. --- tests/library/diff-list-generation-test.cpp | 99 ++++++++++++++++++++- 1 file changed, 95 insertions(+), 4 deletions(-) diff --git a/tests/library/diff-list-generation-test.cpp b/tests/library/diff-list-generation-test.cpp index 6e7d01e8b..b05516604 100644 --- a/tests/library/diff-list-generation-test.cpp +++ b/tests/library/diff-list-generation-test.cpp @@ -23,6 +23,7 @@ #include "lib/test/run.hpp" #include "lib/diff/list-diff.hpp" +#include "lib/iter-adapter.hpp" #include "lib/itertools.hpp" #include "lib/util.hpp" @@ -41,6 +42,18 @@ namespace lib { namespace diff{ //######################### + template + class IndexTable + { + public: + template + IndexTable(SEQ const& seq) + { + UNIMPLEMENTED("build index"); + } + }; + + template class DiffDetector { @@ -49,7 +62,57 @@ namespace diff{ Idx refIdx_; SEQ const& currentData_; + + + using DiffStep = typename ListDiffLanguage::DiffStep; + + /** + * @internal state frame for diff detection and generation. + * A diff generation process is built on top of an "old" reference point + * and a "new" state of the underlying sequence. Within this reference frame, + * an demand-driven evaluation of the differences is handed out to the client + * as an iterator. While consuming this evaluation process, both the old and + * the new version of the sequence will be traversed once. In case of re-orderings, + * a nested forward lookup similar to insertion sort will look for matches in the + * old sequence, rendering the whole evaluation quadratic in worst-case. + */ + class DiffFrame + { + Idx old_; + Idx* new_; + public: + DiffFrame(Idx& current, Idx&& refPoint) + : old_(refPoint) + , new_(¤t) + { } + + + /* === Iteration control API for IterStateWrapper== */ + + friend bool + checkPoint (DiffFrame const& frame) + { + UNIMPLEMENTED("is the diff calculation exhausted?"); + } + + friend DiffStep& + yield (DiffFrame const& frame) + { + REQUIRE (checkPoint (frame)); + UNIMPLEMENTED("yield the diff verb to describe the current point in diff"); + } + + friend void + iterNext (DiffFrame & frame) + { + UNIMPLEMENTED("diff generation core: consume the current state and re-establish the invariant"); + } + }; + + + + public: explicit DiffDetector(SEQ const& refSeq) @@ -57,13 +120,41 @@ namespace diff{ , currentData_(refSeq) { } + + /** does the current state of the underlying sequence differ + * from the state embodied into the last reference snapshot taken? + * @remarks will possibly evaluate and iterate the whole sequence + */ + bool + isChanged() const + { + UNIMPLEMENTED("change detection"); + } + + + /** Diff is a iterator to yield a sequence of DiffStep elements */ + using Diff = lib::IterStateWrapper; + + /** Diff generation core operation. + * Take a snapshot of the \em current state of the underlying sequence + * and establish a frame to find the differences to the previously captured + * \em old state. This possible difference evaluation is embodied into a #Diff + * iterator and handed over to the client, while the snapshot of the current state + * becomes the new reference point from now on. + * @return iterator to yield a sequence of DiffStep tokens, which describe the changes + * between the previous reference state and the current state of the sequence. + * @note takes a new snapshot to supersede the old one, i.e. updates the DiffDetector. + * @warning the returned iterator retains a reference to the current (new) snapshot. + * Any concurrent modification leads to undefined behaviour. You must not + * invoke #pullUpdate while another client still explores the result + * of an old evaluation. + */ Diff pullUpdate() { - Idx newIdx (currentData_); - Diff changes (move(refIdx_), newIdx); - swap (newIdx, refIdx_); - return changes; + Idx mark (currentData_); + swap (mark, refIdx_); // mark now refers to old reference point + return Diff(DiffFrame(refIdx_, move(mark))); } };