chosing an implementation approach for tree-diff-application
This commit is contained in:
parent
c90e6a6f65
commit
e438a9fe51
5 changed files with 208 additions and 3 deletions
78
src/lib/diff/record-content-mutator.hpp
Normal file
78
src/lib/diff/record-content-mutator.hpp
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
RECORD-CONTENT-MUTATOR.hpp - helper to remould record contents
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2015, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/** @file record-content-mutator.hpp
|
||||
** Implementation helper for reshaping the contents of a lib::diff::Record.
|
||||
** This technical helper is necessary to apply one level of a "Tree Diff"
|
||||
** to an object represented as #Record::Mutator. Since records as such are
|
||||
** designed as immutable value objects, we build a dedicated #Record::Mutator
|
||||
** when it comes to reordering the contents of a given record. The technical
|
||||
** details of doing so are highly coupled to the actual storage implementation
|
||||
** of #Record, as well as to the actual procedure to apply a diff message, as
|
||||
** implemented in lib::diff::DiffApplicationStrategy.
|
||||
**
|
||||
** @see generic-record-update-test.cpp
|
||||
** @see tree-diff-application-test.cpp
|
||||
** @see Record::Mutator
|
||||
** @see diff-language.hpp
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIB_DIFF_RECORD_CONTENT_MUTATOR_H
|
||||
#define LIB_DIFF_RECORD_CONTENT_MUTATOR_H
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <utility>
|
||||
|
||||
namespace lib {
|
||||
namespace diff{
|
||||
|
||||
using std::move;
|
||||
using std::swap;
|
||||
|
||||
|
||||
/** @internal helper for DiffApplicationStrategy<Rec::Mutator> */
|
||||
template<class STO>
|
||||
class RecordContentMutator
|
||||
: boost::noncopyable
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
RecordContentMutator()
|
||||
{
|
||||
swap (attribs_, target_.attribs());
|
||||
swap (children_, target_.children());
|
||||
|
||||
// heuristics for storage pre-allocation
|
||||
target_.attribs().reserve (attribs_.size() * 120 / 100);
|
||||
target_.children().reserve (children_.size() * 120 / 100);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace lib::diff
|
||||
#endif /*LIB_DIFF_RECORD_CONTENT_MUTATOR_H*/
|
||||
|
|
@ -27,6 +27,27 @@
|
|||
** to receive linearised structural diff descriptions and apply them to
|
||||
** a given target data structure, to effect the corresponding changes.
|
||||
**
|
||||
** \par Design considerations
|
||||
** While -- conceptually -- our tree diff handling can be seen as an extension
|
||||
** and generalisation of list diffing, the decision was \em not to embody this
|
||||
** extension into the implementation technically, for sake of clarity. More so,
|
||||
** since the Record, which serves as foundation for our »External Tree Description«,
|
||||
** was made to look and behave like a list-like entity, but built with two distinct
|
||||
** scopes at implementation level: the attribute scope and the contents scope. This
|
||||
** carries over to the fine points of the list diff language semantics, especially
|
||||
** when it comes to fault tolerance and strictness vs fuzziness in diff application.
|
||||
** The implementation is thus faced with having to deal with an internal focus and
|
||||
** a switch from scope to scope, which adds a lot of complexity. So the list diff
|
||||
** application strategy can be seen as blueprint and demonstration of principles.
|
||||
**
|
||||
** Another point in question is weather see the diff application as manipulating
|
||||
** a target data structure, or rather building a reshaped copy. The fact that
|
||||
** GenNode and Record are designed as immutable values seems to favour the latter,
|
||||
** yet the very reason to engage into building this diff framework was how to
|
||||
** handle partial updates within a expectedly very large UI model, reflecting
|
||||
** the actual session model in Proc-Layer. So we end up working on a Mutator,
|
||||
** which clearly signals we're going to reshape and re-rig the target data.
|
||||
**
|
||||
** @see diff-list-application-test.cpp
|
||||
** @see VerbToken
|
||||
**
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@
|
|||
/** @file tree-diff.hpp
|
||||
** A token language to represent structural changes in a tree like
|
||||
** hierarchical data structure. In combination with the #DiffLanguage framework,
|
||||
** this building block defines the set of operations to express both content
|
||||
** and structural changes in a given data structure.
|
||||
** this building block defines the set of operations to express both structural
|
||||
** and content changes in a given data structure.
|
||||
**
|
||||
** @todo UNIMPLEMENTED as of 12/14
|
||||
**
|
||||
|
|
|
|||
86
tests/library/diff/generic-record-update-test.cpp
Normal file
86
tests/library/diff/generic-record-update-test.cpp
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
GenericRecordUpdate(Test) - manipulate and reshape the generic record contents
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2015, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/diff/record-content-mutator.hpp"
|
||||
//#include "lib/iter-adapter-stl.hpp"
|
||||
//#include "lib/time/timevalue.hpp"
|
||||
//#include "lib/format-util.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//using lib::iter_stl::snapshot;
|
||||
using util::isnil;
|
||||
//using util::join;
|
||||
//using std::string;
|
||||
using std::vector;
|
||||
//using lib::time::Time;
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace diff{
|
||||
namespace test{
|
||||
|
||||
namespace {//Test fixture....
|
||||
|
||||
}//(End)Test fixture
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************//**
|
||||
* @test cover technical details of rearranging the contents of lib::diff::Record.
|
||||
* The implementation of our generic record (abstract object representation)
|
||||
* uses two lists to hold the data of the attribute and content scopes.
|
||||
* When receiving a diff message, we have to rearrange and alter the contents,
|
||||
* which are by default immutable. Thus, for this specific task, embedded
|
||||
* data is moved into this adapter, which exposes the mutating operation
|
||||
* required to apply such a diff message.
|
||||
*
|
||||
* @see generic-record-representation-test.cpp
|
||||
* @see tree-diff-application-test.cpp
|
||||
*/
|
||||
class GenericRecordUpdate_test
|
||||
: public Test
|
||||
{
|
||||
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (GenericRecordUpdate_test, "unit common");
|
||||
|
||||
|
||||
|
||||
}}} // namespace lib::diff::test
|
||||
|
|
@ -1852,7 +1852,27 @@
|
|||
</node>
|
||||
<node CREATED="1445392105075" ID="ID_1377567733" MODIFIED="1445392113677" TEXT="zwei neue, lokale Vektoren aufbauen"/>
|
||||
<node CREATED="1445392114217" ID="ID_71124283" MODIFIED="1445392120973" TEXT="daraus den neuen Record konstruieren"/>
|
||||
<node CREATED="1445556634395" ID="ID_1143865339" MODIFIED="1445556649348" TEXT="technische Komplikation: "2 Listen"-Modell"/>
|
||||
<node CREATED="1445556634395" ID="ID_1143865339" MODIFIED="1445621027321" TEXT="technische Komplikation: "2 Listen"-Modell">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1445620914088" ID="ID_1919426539" MODIFIED="1445621018036" TEXT="Verhalten ändert sich je nach Scope">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1445620938421" ID="ID_557124057" MODIFIED="1445621022038" TEXT="Verzweigung in jedem Diff-Fall">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1445620947332" ID="ID_1684844100" MODIFIED="1445621010162" TEXT="Code-Redundanz">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
<node CREATED="1445620961570" ID="ID_965863635" MODIFIED="1445621006245" TEXT="in Wrapper wegpacken!">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1445620972825" ID="ID_1467461119" MODIFIED="1445621002208" TEXT="schon in den Record::Mutator einbinden">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1445620991326" ID="ID_513677356" MODIFIED="1445620998003" TEXT="eigener Test">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue