chosing an implementation approach for tree-diff-application

This commit is contained in:
Fischlurch 2015-10-23 19:24:34 +02:00
parent c90e6a6f65
commit e438a9fe51
5 changed files with 208 additions and 3 deletions

View 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*/

View file

@ -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
**

View file

@ -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
**

View 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

View file

@ -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: &quot;2 Listen&quot;-Modell"/>
<node CREATED="1445556634395" ID="ID_1143865339" MODIFIED="1445621027321" TEXT="technische Komplikation: &quot;2 Listen&quot;-Modell">
<icon BUILTIN="pencil"/>
<node CREATED="1445620914088" ID="ID_1919426539" MODIFIED="1445621018036" TEXT="Verhalten &#xe4;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>