Version: 9.15.0
SUIT_TreeSync.h
Go to the documentation of this file.
1 // Copyright (C) 2007-2025 CEA, EDF, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 
23 // File : SUIT_TreeSync.h
24 // Author : Alexander SOLOVYOV
25 //
26 #ifndef SUIT_TREESYNC_H
27 #define SUIT_TREESYNC_H
28 
29 #include <QList>
30 
41 template <class SrcItem, class TrgItem>
42 struct DiffItem
43 {
44  SrcItem mySrc;
45  TrgItem myTrg;
46 };
47 
48 
49 //
50 // Function prototypes.
51 //
52 
53 template <class SrcItem, class TrgItem, class TreeData>
54 TrgItem synchronize( const SrcItem&, const TrgItem&, const TreeData& );
55 
56 template <class SrcItem, class TrgItem, class TreeData>
58  const TrgItem&,
59  const TreeData& );
60 
61 template <class SrcItem, class TrgItem, class TreeData>
62 TrgItem createSubTree( const SrcItem&, const TrgItem&, const TrgItem&, const TreeData& );
63 
64 template <class SrcItem, class TrgItem, class TreeData>
65 const typename QList<TrgItem>::const_iterator findEqual( const SrcItem& it,
66  const typename QList<TrgItem>::const_iterator& first,
67  const typename QList<TrgItem>::const_iterator& last,
68  const TreeData& td );
69 
70 
71 //
72 // Function imlpementation.
73 //
74 
117 template <class SrcItem, class TrgItem, class TreeData>
118 TrgItem synchronize( const SrcItem& r1, const TrgItem& r2, const TreeData& td )
119 {
120  if ( td.isEqual( r1, r2 ) ) {
121  // update items themselves
122  td.updateItem( r1, r2 );
123 
124  // iterate through children
126 
127  typename QList< DiffItem< SrcItem, TrgItem > >::const_iterator anIt = d.begin(), aLast = d.end();
128  TrgItem lastItem = td.nullTrg();
129 
130  for ( ; anIt != aLast; anIt++ ) {
131  const DiffItem<SrcItem,TrgItem>& item = *anIt;
132  if ( item.mySrc == td.nullSrc() ) {
133  if ( item.myTrg == td.nullTrg() )
134  {
135 #ifdef _DEBUG_
136  qDebug( "error: both null" );
137 #endif
138  }
139  else
140  // delete item
141  td.deleteItemWithChildren( item.myTrg );
142  }
143  else {
144  if ( item.myTrg == td.nullTrg() ) {
145  // add item (recursively)
146  TrgItem nitem = createSubTree( item.mySrc, r2, lastItem, td );
147  if ( nitem != td.nullTrg() )
148  lastItem = nitem;
149  }
150  else {
151  // update item
152  synchronize( item.mySrc, item.myTrg, td );
153  lastItem = item.myTrg;
154  }
155  }
156  }
157  return r2;
158  }
159  else {
160  TrgItem new_r2 = td.nullTrg();
161  if ( r1 != td.nullSrc() ) {
162  // add new item (recursively)
163  new_r2 = createSubTree( r1, td.parent( r2 ), r2, td );
164  }
165  if ( r2 != td.nullTrg() ) {
166  // delete old one (if it is not null)
167  td.deleteItemWithChildren( r2 );
168  }
169  return new_r2;
170  }
171 }
172 
183 template <class SrcItem, class TrgItem, class TreeData>
184 const typename QList<TrgItem>::const_iterator findEqual( const SrcItem& it,
185  const typename QList<TrgItem>::const_iterator& first,
186  const typename QList<TrgItem>::const_iterator& last,
187  const TreeData& td )
188 {
189  typename QList<TrgItem>::const_iterator cur = first;
190  for ( ; cur != last; cur++ ) {
191  if ( td.isEqual( it, *cur ) )
192  return cur;
193  }
194  return last;
195 }
196 
205 template <class SrcItem, class TrgItem, class TreeData>
206 QList< DiffItem<SrcItem,TrgItem> > diffSiblings( const SrcItem& src, const TrgItem& trg,
207  const TreeData& td )
208 {
209  //if( src==td.nullSrc() || trg==td.nullTrg() )
210  // return;
211 
213 
214  QList<SrcItem> src_ch = td.children( src );
215  QList<TrgItem> trg_ch = td.children( trg );
216 
217  typename QList<SrcItem>::const_iterator src_it = src_ch.begin(), src_last = src_ch.end();
218  typename QList<TrgItem>::const_iterator cur = trg_ch.begin(), trg_last = trg_ch.end();
219 
220  for ( ; src_it != src_last; src_it++ ) {
221  typename QList<TrgItem>::const_iterator f =
222  findEqual<SrcItem, TrgItem, TreeData>( *src_it, cur, trg_last, td );
223  if ( f != trg_last ) {
224  // target is found
225  // mark all items before found one as "to be deleted"
226  for ( typename QList<TrgItem>::const_iterator it = cur; it != f; it++ ) {
228  ndiff.mySrc = td.nullSrc();
229  ndiff.myTrg = *it; // delete item
230  d.append( ndiff );
231  }
232  cur = f;
234  ndiff.mySrc = *src_it;
235  ndiff.myTrg = *cur; // update this (found) item
236  d.append( ndiff );
237  cur++;
238  }
239  else {
240  // target is not found
242  ndiff.mySrc = *src_it;
243  ndiff.myTrg = td.nullTrg(); // add item
244  d.append( ndiff );
245  }
246  }
247  // delete rest items
248  for ( ; cur != trg_last; cur++ ) {
250  ndiff.mySrc = td.nullSrc();
251  ndiff.myTrg = *cur; // delete item
252  d.append( ndiff );
253  }
254 
255  return d;
256 }
257 
267 template <class SrcItem, class TrgItem, class TreeData>
268 TrgItem createSubTree( const SrcItem& src, const TrgItem& parent,
269  const TrgItem& after, const TreeData& td )
270 {
271  if ( src == td.nullSrc() )
272  return td.nullTrg();
273 
274  TrgItem nitem = td.createItem( src, parent, after );
275  if ( nitem == td.nullTrg() )
276  return nitem;
277 
278  QList<SrcItem> ch = td.children( src );
279  typename QList<SrcItem>::const_iterator anIt = ch.begin(), aLast = ch.end();
280  TrgItem last = td.nullTrg();
281  for( ; anIt != aLast; anIt++ )
282  last = createSubTree( *anIt, nitem, last, td );
283 
284  return nitem;
285 }
286 
287 #endif // SUIT_TREESYNC_H
TrgItem synchronize(const SrcItem &, const TrgItem &, const TreeData &)
Synchronize two data trees by recurive comparing of the corresponding items.
Definition: SUIT_TreeSync.h:118
QList< DiffItem< SrcItem, TrgItem > > diffSiblings(const SrcItem &, const TrgItem &, const TreeData &)
Compare children of the source and target trees to find differences.
Definition: SUIT_TreeSync.h:206
const QList< TrgItem >::const_iterator findEqual(const SrcItem &it, const typename QList< TrgItem >::const_iterator &first, const typename QList< TrgItem >::const_iterator &last, const TreeData &td)
Find the item in the target tree which correspond to the specified source tree item.
Definition: SUIT_TreeSync.h:184
TrgItem createSubTree(const SrcItem &, const TrgItem &, const TrgItem &, const TreeData &)
Create an item with all its children recursively in the target tree.
Definition: SUIT_TreeSync.h:268
The structure representing difference between source and destination items.
Definition: SUIT_TreeSync.h:43
SrcItem mySrc
source tree item
Definition: SUIT_TreeSync.h:44
TrgItem myTrg
target tree item
Definition: SUIT_TreeSync.h:45