on second thought: yet a better solution
...is to let the diff applicator work *on* a Rec::Mutator This is outright natural -- why is it that I needed 2 days to come up with this solution?
This commit is contained in:
parent
eabeee3b7b
commit
c90e6a6f65
5 changed files with 59 additions and 65 deletions
|
|
@ -296,7 +296,6 @@ namespace diff{
|
|||
{
|
||||
for ( ; diff; ++diff )
|
||||
diff->applyTo(target_);
|
||||
target_.finalise();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -167,9 +167,6 @@ namespace diff{
|
|||
swap (seq_, orig_); // pos_ still refers to original input sequence, which has been moved to orig_
|
||||
seq_.reserve (targetVector.size() * 120 / 100); // heuristics for storage pre-allocation
|
||||
}
|
||||
|
||||
/** clean-up and make changes effective within target */
|
||||
void finalise() { /* NOP for this implementation */ }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -40,20 +40,34 @@
|
|||
#include "lib/diff/tree-diff.hpp"
|
||||
#include "lib/diff/gen-node.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace lib {
|
||||
namespace diff{
|
||||
|
||||
using std::move;
|
||||
using std::swap;
|
||||
|
||||
|
||||
/**
|
||||
* concrete strategy to apply a structural diff to a target data structure
|
||||
* made from #Record<GenNode> elements.
|
||||
* made from #Record<GenNode> elements. This data structure is assumed to be
|
||||
* recursive, tree-like. But because Record elements are conceived as immutable
|
||||
* and value-like, the tree diff application actually works on a Rec::Mutator
|
||||
* wrapping the target record to be altered through consuming the diff.
|
||||
* @throws lumiera::error::State when diff application fails due to the
|
||||
* target sequence being different than assumed by the given diff.
|
||||
* @see #TreeDiffInterpreter explanation of the verbs
|
||||
*/
|
||||
template<>
|
||||
class DiffApplicationStrategy<Rec>
|
||||
class DiffApplicationStrategy<Rec::Mutator>
|
||||
: public TreeDiffInterpreter
|
||||
{
|
||||
using Storage = RecordSetup<GenNode>::Storage;
|
||||
|
||||
Rec::Mutator& target_;
|
||||
Storage attribs_;
|
||||
Storage children_;
|
||||
|
||||
|
||||
/* == Implementation of the list diff application primitives == */
|
||||
|
|
@ -113,16 +127,17 @@ namespace diff{
|
|||
|
||||
public:
|
||||
explicit
|
||||
DiffApplicationStrategy(Rec& targetRecord)
|
||||
DiffApplicationStrategy(Rec::Mutator& mutableTargetRecord)
|
||||
: target_(mutableTargetRecord)
|
||||
, attribs_()
|
||||
, children_()
|
||||
{
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
/** clean-up and make changes effective within target */
|
||||
void
|
||||
finalise()
|
||||
{
|
||||
UNIMPLEMENTED("push rebuilt Record into target");
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -138,16 +138,17 @@ namespace test{
|
|||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
Rec target;
|
||||
DiffApplicator<Rec> application(target);
|
||||
Rec::Mutator target;
|
||||
Rec& subject = target;
|
||||
DiffApplicator<Rec::Mutator> application(target);
|
||||
application.consume(populationDiff());
|
||||
|
||||
CHECK (!isnil (target)); // nonempty -- content has been added
|
||||
CHECK ("X" == target.getType()); // type was set to "X"
|
||||
CHECK (1 == target.get("α").data.get<int>()); // has gotten our int attribute "α"
|
||||
CHECK (2L == target.get("β").data.get<int64_t>()); // ... the long attribute "β"
|
||||
CHECK (3.45 == target.get("γ").data.get<double>()); // ... and double attribute "γ"
|
||||
auto scope = target.scope(); // look into the scope contents...
|
||||
CHECK (!isnil (subject)); // nonempty -- content has been added
|
||||
CHECK ("X" == subject.getType()); // type was set to "X"
|
||||
CHECK (1 == subject.get("α").data.get<int>()); // has gotten our int attribute "α"
|
||||
CHECK (2L == subject.get("β").data.get<int64_t>()); // ... the long attribute "β"
|
||||
CHECK (3.45 == subject.get("γ").data.get<double>()); // ... and double attribute "γ"
|
||||
auto scope = subject.scope(); // look into the scope contents...
|
||||
CHECK ( *scope == CHILD_A); // there is CHILD_A
|
||||
CHECK (*++scope == CHILD_T); // followed by a copy of CHILD_T
|
||||
CHECK (*++scope == CHILD_T); // and another copy of CHILD_T
|
||||
|
|
@ -157,8 +158,8 @@ namespace test{
|
|||
CHECK (isnil(++scope)); // thats all -- no more children
|
||||
|
||||
application.consume(mutationDiff());
|
||||
CHECK (join (target.keys()) == "α, β, γ"); // the attributes weren't altered
|
||||
scope = target.scope(); // but the scope was reordered
|
||||
CHECK (join (subject.keys()) == "α, β, γ"); // the attributes weren't altered
|
||||
scope = subject.scope(); // but the scope was reordered
|
||||
CHECK ( *scope == CHILD_T); // CHILD_T
|
||||
CHECK (*++scope == CHILD_A); // CHILD_A
|
||||
Rec nested = (++scope)->data.get<Rec>(); // and our nested Record, which too has been altered:
|
||||
|
|
|
|||
|
|
@ -1810,7 +1810,27 @@
|
|||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1445550873904" ID="ID_1781797833" MODIFIED="1445550888011" TEXT="copy + transaktional als 2.Layer"/>
|
||||
<node CREATED="1445555721981" ID="ID_292803227" MODIFIED="1445556598964">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Lösung: wir arbeiten <i>auf </i>einem Mutator
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1445556525714" ID="ID_1223708278" MODIFIED="1445556595037" TEXT="damit funktioniert es 1:1 wie List-Diff">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node CREATED="1445556567980" ID="ID_783100840" MODIFIED="1445556591370" TEXT="Voraussetzung: der Mutator muß die Attribut/Kinder-Listen exponieren">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1445550873904" ID="ID_1781797833" MODIFIED="1445556509368" TEXT="copy + transaktional als optionaler 2.Layer"/>
|
||||
<node CREATED="1445550893222" ID="ID_2118555" MODIFIED="1445550915111" TEXT="Diff-Applikator = destruktiver Mutator"/>
|
||||
<node CREATED="1445389311690" ID="ID_1926972913" MODIFIED="1445389323819" TEXT="und dieses rekursiv..."/>
|
||||
</node>
|
||||
|
|
@ -1832,45 +1852,7 @@
|
|||
</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="1445392127015" ID="ID_883189076" MODIFIED="1445392201654">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Problem: Konstruktion <i>nach </i>Diff
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1445392161508" ID="ID_425268274" MODIFIED="1445392188383" TEXT="API dafür fehlt">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1445392169019" ID="ID_475848296" MODIFIED="1445392193215" TEXT="doppelte Hülle">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1445392174969" ID="ID_387417089" MODIFIED="1445392183796" TEXT="DiffAplicator ist generisch">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1445550928897" ID="ID_911120047" MODIFIED="1445551003670" TEXT="-> muß inneres API erweitern">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
d.h. es gibt eine Methode applyChanges.
|
||||
</p>
|
||||
<p>
|
||||
Die generische Implementierung verwendet diese nach Aufspielen des Diff
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1445556634395" ID="ID_1143865339" MODIFIED="1445556649348" TEXT="technische Komplikation: "2 Listen"-Modell"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue