Guitar
Diff.hpp
Go to the documentation of this file.
1 
36 /* If you use this library, you must include dtl.hpp only. */
37 
38 #ifndef DTL_DIFF_H
39 #define DTL_DIFF_H
40 
41 #include "variables.hpp"
42 
43 namespace dtl {
44 
49  template <typename elem, typename sequence = vector< elem >, typename comparator = Compare< elem > >
50  class Diff
51  {
52  private :
53  dtl_typedefs(elem, sequence)
54  sequence A;
55  sequence B;
56  size_t M;
57  size_t N;
58  size_t delta;
59  size_t offset;
60  long long *fp;
61  long long editDistance;
66  bool swapped;
67  bool huge;
68  bool trivial;
70  uniHunkVec uniHunks;
71  comparator cmp;
72  long long ox;
73  long long oy;
74  public :
75  Diff () {}
76 
77  Diff (const sequence& a,
78  const sequence& b) : A(a), B(b), ses(false) {
79  init();
80  }
81 
82  Diff (const sequence& a,
83  const sequence& b,
84  bool deletesFirst) : A(a), B(b), ses(deletesFirst) {
85  init();
86  }
87 
88  Diff (const sequence& a,
89  const sequence& b,
90  const comparator& comp) : A(a), B(b), ses(false), cmp(comp) {
91  init();
92  }
93 
94  Diff (const sequence& a,
95  const sequence& b,
96  bool deleteFirst,
97  const comparator& comp) : A(a), B(b), ses(deleteFirst), cmp(comp) {
98  init();
99  }
100 
101  ~Diff() {}
102 
103  long long getEditDistance () const {
104  return editDistance;
105  }
106 
107  Lcs< elem > getLcs () const {
108  return lcs;
109  }
110 
111  elemVec getLcsVec () const {
112  return lcs.getSequence();
113  }
114 
115  Ses< elem > getSes () const {
116  return ses;
117  }
118 
119  uniHunkVec getUniHunks () const {
120  return uniHunks;
121  }
122 
123  /* These should be deprecated */
124  bool isHuge () const {
125  return huge;
126  }
127 
128  void onHuge () {
129  this->huge = true;
130  }
131 
132  void offHuge () {
133  this->huge = false;
134  }
135 
136  bool isUnserious () const {
137  return trivial;
138  }
139 
140  void onUnserious () {
141  this->trivial = true;
142  }
143 
144  void offUnserious () {
145  this->trivial = false;
146  }
147 
149  this->editDistanceOnly = true;
150  }
151 
152  /* These are the replacements for the above */
153  bool hugeEnabled () const {
154  return huge;
155  }
156 
157  void enableHuge () {
158  this->huge = true;
159  }
160 
161  void disableHuge () {
162  this->huge = false;
163  }
164 
165  bool trivialEnabled () const {
166  return trivial;
167  }
168 
169  void enableTrivial () {
170  this->trivial = true;
171  }
172 
173  void disableTrivial () {
174  this->trivial = false;
175  }
176 
178  this->editDistanceOnly = true;
179  }
180 
184  sequence uniPatch (const sequence& seq) {
185  elemList seqLst(seq.begin(), seq.end());
186  sesElemVec shunk;
187  sesElemVec_iter vsesIt;
188  elemList_iter lstIt = seqLst.begin();
189  long long inc_dec_total = 0;
190  long long gap = 1;
191  for (uniHunkVec_iter it=uniHunks.begin();it!=uniHunks.end();++it) {
192  joinSesVec(shunk, it->common[0]);
193  joinSesVec(shunk, it->change);
194  joinSesVec(shunk, it->common[1]);
195  it->a += inc_dec_total;
196  inc_dec_total += it->inc_dec_count;
197  for (long long i=0;i<it->a - gap;++i) {
198  ++lstIt;
199  }
200  gap = it->a + it->b + it->inc_dec_count;
201  vsesIt = shunk.begin();
202  while (vsesIt!=shunk.end()) {
203  switch (vsesIt->second.type) {
204  case SES_ADD :
205  seqLst.insert(lstIt, vsesIt->first);
206  break;
207  case SES_DELETE :
208  if (lstIt != seqLst.end()) {
209  lstIt = seqLst.erase(lstIt);
210  }
211  break;
212  case SES_COMMON :
213  if (lstIt != seqLst.end()) {
214  ++lstIt;
215  }
216  break;
217  default :
218  // no fall-through
219  break;
220  }
221  ++vsesIt;
222  }
223  shunk.clear();
224  }
225 
226  sequence patchedSeq(seqLst.begin(), seqLst.end());
227  return patchedSeq;
228  }
229 
233  sequence patch (const sequence& seq) const {
234  sesElemVec sesSeq = ses.getSequence();
235  elemList seqLst(seq.begin(), seq.end());
236  elemList_iter lstIt = seqLst.begin();
237  for (sesElemVec_iter sesIt=sesSeq.begin();sesIt!=sesSeq.end();++sesIt) {
238  switch (sesIt->second.type) {
239  case SES_ADD :
240  seqLst.insert(lstIt, sesIt->first);
241  break;
242  case SES_DELETE :
243  lstIt = seqLst.erase(lstIt);
244  break;
245  case SES_COMMON :
246  ++lstIt;
247  break;
248  default :
249  // no through
250  break;
251  }
252  }
253  sequence patchedSeq(seqLst.begin(), seqLst.end());
254  return patchedSeq;
255  }
256 
262  void compose() {
263 
264  if (isHuge()) {
266  }
267  ox = 0;
268  oy = 0;
269  long long p = -1;
270  fp = new long long[M + N + 3];
271  fill(&fp[0], &fp[M + N + 3], -1);
272  path = editPath(M + N + 3);
273  fill(path.begin(), path.end(), -1);
274  ONP:
275  do {
276  ++p;
277  for (long long k=-p;k<=static_cast<long long>(delta)-1;++k) {
278  fp[k+offset] = snake(k, fp[k-1+offset]+1, fp[k+1+offset]);
279  }
280  for (long long k=static_cast<long long>(delta)+p;k>=static_cast<long long>(delta)+1;--k) {
281  fp[k+offset] = snake(k, fp[k-1+offset]+1, fp[k+1+offset]);
282  }
283  fp[delta+offset] = snake(static_cast<long long>(delta), fp[delta-1+offset]+1, fp[delta+1+offset]);
284  } while (fp[delta+offset] != static_cast<long long>(N) && pathCordinates.size() < MAX_CORDINATES_SIZE);
285 
286  editDistance += static_cast<long long>(delta) + 2 * p;
287  long long r = path[delta+offset];
288  P cordinate;
289  editPathCordinates epc(0);
290 
291  // recording edit distance only
292  if (editDistanceOnly) {
293  delete[] this->fp;
294  return;
295  }
296 
297  while(r != -1) {
298  cordinate.x = pathCordinates[(size_t)r].x;
299  cordinate.y = pathCordinates[(size_t)r].y;
300  epc.push_back(cordinate);
301  r = pathCordinates[(size_t)r].k;
302  }
303 
304  // record Longest Common Subsequence & Shortest Edit Script
305  if (!recordSequence(epc)) {
306  pathCordinates.resize(0);
307  epc.resize(0);
308  p = -1;
309  goto ONP;
310  }
311  delete[] this->fp;
312  }
313 
317  template < typename stream >
318  void printSES (stream& out) const {
319  sesElemVec ses_v = ses.getSequence();
320  for_each(ses_v.begin(), ses_v.end(), ChangePrinter< sesElem, stream >(out));
321  }
322 
323  void printSES (ostream& out = cout) const {
324  printSES< ostream >(out);
325  }
326 
330  template < typename stream >
331  static void printSES (const Ses< elem >& s, stream& out) {
332  sesElemVec ses_v = s.getSequence();
333  for_each(ses_v.begin(), ses_v.end(), ChangePrinter< sesElem, stream >(out));
334  }
335 
336  static void printSES (const Ses< elem >& s, ostream& out = cout) {
337  printSES< ostream >(s, out);
338  }
339 
343  template < typename stream, template < typename SEET, typename STRT > class PT >
344  void printSES (stream& out) const {
345  sesElemVec ses_v = ses.getSequence ();
346  for_each (ses_v.begin (), ses_v.end(), PT < sesElem, stream > (out));
347  }
348 
352  template < typename storedData, template < typename SEET, typename STRT > class ST >
353  void storeSES(storedData& sd) const {
354  sesElemVec ses_v = ses.getSequence();
355  for_each(ses_v.begin(), ses_v.end(), ST < sesElem, storedData >(sd));
356  }
357 
361  template < typename stream >
362  void printUnifiedFormat (stream& out) const {
363  for_each(uniHunks.begin(), uniHunks.end(), UniHunkPrinter< sesElem, stream >(out));
364  }
365 
366  void printUnifiedFormat (ostream& out = cout) const {
367  printUnifiedFormat< ostream >(out);
368  }
369 
373  template < typename stream >
374  static void printUnifiedFormat (const uniHunkVec& hunks, stream& out) {
375  for_each(hunks.begin(), hunks.end(), UniHunkPrinter< sesElem >(out));
376  }
377 
378  static void printUnifiedFormat (const uniHunkVec& hunks, ostream& out = cout) {
379  printUnifiedFormat< ostream >(hunks, out);
380  }
381 
386  sesElemVec common[2];
387  sesElemVec change;
388  sesElemVec ses_v = ses.getSequence();
389  long long l_cnt = 1;
390  long long length = distance(ses_v.begin(), ses_v.end());
391  long long middle = 0;
392  bool isMiddle, isAfter;
393  elemInfo einfo;
394  long long a, b, c, d; // @@ -a,b +c,d @@
395  long long inc_dec_count = 0;
396  uniHunk< sesElem > hunk;
397  sesElemVec adds;
398  sesElemVec deletes;
399 
400  isMiddle = isAfter = false;
401  a = b = c = d = 0;
402 
403  for (sesElemVec_iter it=ses_v.begin();it!=ses_v.end();++it, ++l_cnt) {
404  einfo = it->second;
405  switch (einfo.type) {
406  case SES_ADD :
407  middle = 0;
408  ++inc_dec_count;
409  adds.push_back(*it);
410  if (!isMiddle) isMiddle = true;
411  if (isMiddle) ++d;
412  if (l_cnt >= length) {
413  joinSesVec(change, deletes);
414  joinSesVec(change, adds);
415  isAfter = true;
416  }
417  break;
418  case SES_DELETE :
419  middle = 0;
420  --inc_dec_count;
421  deletes.push_back(*it);
422  if (!isMiddle) isMiddle = true;
423  if (isMiddle) ++b;
424  if (l_cnt >= length) {
425  joinSesVec(change, deletes);
426  joinSesVec(change, adds);
427  isAfter = true;
428  }
429  break;
430  case SES_COMMON :
431  ++b;++d;
432  if (common[1].empty() && adds.empty() && deletes.empty() && change.empty()) {
433  if (static_cast<long long>(common[0].size()) < DTL_CONTEXT_SIZE) {
434  if (a == 0 && c == 0) {
435  if (!wasSwapped()) {
436  a = einfo.beforeIdx;
437  c = einfo.afterIdx;
438  } else {
439  a = einfo.afterIdx;
440  c = einfo.beforeIdx;
441  }
442  }
443  common[0].push_back(*it);
444  } else {
445  rotate(common[0].begin(), common[0].begin() + 1, common[0].end());
446  common[0].pop_back();
447  common[0].push_back(*it);
448  ++a;++c;
449  --b;--d;
450  }
451  }
452  if (isMiddle && !isAfter) {
453  ++middle;
454  joinSesVec(change, deletes);
455  joinSesVec(change, adds);
456  change.push_back(*it);
457  if (middle >= DTL_SEPARATE_SIZE || l_cnt >= length) {
458  isAfter = true;
459  }
460  adds.clear();
461  deletes.clear();
462  }
463  break;
464  default :
465  // no through
466  break;
467  }
468  // compose unified format hunk
469  if (isAfter && !change.empty()) {
470  sesElemVec_iter cit = it;
471  long long cnt = 0;
472  for (long long i=0;i<DTL_SEPARATE_SIZE && (cit != ses_v.end());++i, ++cit) {
473  if (cit->second.type == SES_COMMON) {
474  ++cnt;
475  }
476  }
477  if (cnt < DTL_SEPARATE_SIZE && l_cnt < length) {
478  middle = 0;
479  isAfter = false;
480  continue;
481  }
482  if (static_cast<long long>(common[0].size()) >= DTL_SEPARATE_SIZE) {
483  long long c0size = static_cast<long long>(common[0].size());
484  rotate(common[0].begin(),
485  common[0].begin() + (size_t)c0size - DTL_SEPARATE_SIZE,
486  common[0].end());
487  for (long long i=0;i<c0size - DTL_SEPARATE_SIZE;++i) {
488  common[0].pop_back();
489  }
490  a += c0size - DTL_SEPARATE_SIZE;
491  c += c0size - DTL_SEPARATE_SIZE;
492  }
493  if (a == 0) ++a;
494  if (c == 0) ++c;
495  if (wasSwapped()) swap(a, c);
496  hunk.a = a;
497  hunk.b = b;
498  hunk.c = c;
499  hunk.d = d;
500  hunk.common[0] = common[0];
501  hunk.change = change;
502  hunk.common[1] = common[1];
503  hunk.inc_dec_count = inc_dec_count;
504  uniHunks.push_back(hunk);
505  isMiddle = false;
506  isAfter = false;
507  common[0].clear();
508  common[1].clear();
509  adds.clear();
510  deletes.clear();
511  change.clear();
512  a = b = c = d = middle = inc_dec_count = 0;
513  }
514  }
515  }
516 
520  template <typename stream>
521  static Ses< elem > composeSesFromStream (stream& st)
522  {
523  elem line;
524  Ses< elem > ret;
525  long long x_idx, y_idx;
526  x_idx = y_idx = 1;
527  while (getline(st, line)) {
528  elem mark(line.begin(), line.begin() + 1);
529  elem e(line.begin() + 1, line.end());
530  if (mark == SES_MARK_DELETE) {
531  ret.addSequence(e, x_idx, 0, SES_DELETE);
532  ++x_idx;
533  } else if (mark == SES_MARK_ADD) {
534  ret.addSequence(e, y_idx, 0, SES_ADD);
535  ++y_idx;
536  } else if (mark == SES_MARK_COMMON) {
537  ret.addSequence(e, x_idx, y_idx, SES_COMMON);
538  ++x_idx;
539  ++y_idx;
540  }
541  }
542  return ret;
543  }
544 
545  private :
549  void init () {
550  M = distance(A.begin(), A.end());
551  N = distance(B.begin(), B.end());
552  if (M < N) {
553  swapped = false;
554  } else {
555  swap(A, B);
556  swap(M, N);
557  swapped = true;
558  }
559  editDistance = 0;
560  delta = N - M;
561  offset = M + 1;
562  huge = false;
563  trivial = false;
564  editDistanceOnly = false;
565  fp = NULL;
566  }
567 
571  long long snake(const long long& k, const long long& above, const long long& below) {
572  long long r = above > below ? path[(size_t)k-1+offset] : path[(size_t)k+1+offset];
573  long long y = max(above, below);
574  long long x = y - k;
575  while ((size_t)x < M && (size_t)y < N && (swapped ? cmp.impl(B[(size_t)y], A[(size_t)x]) : cmp.impl(A[(size_t)x], B[(size_t)y]))) {
576  ++x;++y;
577  }
578 
579  path[(size_t)k+offset] = static_cast<long long>(pathCordinates.size());
580  if (!editDistanceOnly) {
581  P p;
582  p.x = x;p.y = y;p.k = r;
583  pathCordinates.push_back(p);
584  }
585  return y;
586  }
587 
592  sequence_const_iter x(A.begin());
593  sequence_const_iter y(B.begin());
594  long long x_idx, y_idx; // line number for Unified Format
595  long long px_idx, py_idx; // cordinates
596  bool complete = false;
597  x_idx = y_idx = 1;
598  px_idx = py_idx = 0;
599  for (size_t i=v.size()-1;!complete;--i) {
600  while(px_idx < v[i].x || py_idx < v[i].y) {
601  if (v[i].y - v[i].x > py_idx - px_idx) {
602  if (!wasSwapped()) {
603  ses.addSequence(*y, 0, y_idx + oy, SES_ADD);
604  } else {
605  ses.addSequence(*y, y_idx + oy, 0, SES_DELETE);
606  }
607  ++y;
608  ++y_idx;
609  ++py_idx;
610  } else if (v[i].y - v[i].x < py_idx - px_idx) {
611  if (!wasSwapped()) {
612  ses.addSequence(*x, x_idx + ox, 0, SES_DELETE);
613  } else {
614  ses.addSequence(*x, 0, x_idx + ox, SES_ADD);
615  }
616  ++x;
617  ++x_idx;
618  ++px_idx;
619  } else {
620  if (!wasSwapped()) {
621  lcs.addSequence(*x);
622  ses.addSequence(*x, x_idx + ox, y_idx + oy, SES_COMMON);
623  } else {
624  lcs.addSequence(*y);
625  ses.addSequence(*y, y_idx + oy, x_idx + ox, SES_COMMON);
626  }
627  ++x;
628  ++y;
629  ++x_idx;
630  ++y_idx;
631  ++px_idx;
632  ++py_idx;
633  }
634  }
635  if (i == 0) complete = true;
636  }
637 
638  if (x_idx > static_cast<long long>(M) && y_idx > static_cast<long long>(N)) {
639  // all recording succeeded
640  } else {
641  // trivial difference
642  if (trivialEnabled()) {
643  if (!wasSwapped()) {
644  recordOddSequence(x_idx, M, x, SES_DELETE);
645  recordOddSequence(y_idx, N, y, SES_ADD);
646  } else {
647  recordOddSequence(x_idx, M, x, SES_ADD);
648  recordOddSequence(y_idx, N, y, SES_DELETE);
649  }
650  return true;
651  }
652 
653  // nontrivial difference
654  sequence A_(A.begin() + (size_t)x_idx - 1, A.end());
655  sequence B_(B.begin() + (size_t)y_idx - 1, B.end());
656  A = A_;
657  B = B_;
658  M = distance(A.begin(), A.end());
659  N = distance(B.begin(), B.end());
660  delta = N - M;
661  offset = M + 1;
662  delete[] fp;
663  fp = new long long[M + N + 3];
664  fill(&fp[0], &fp[M + N + 3], -1);
665  fill(path.begin(), path.end(), -1);
666  ox = x_idx - 1;
667  oy = y_idx - 1;
668  return false;
669  }
670  return true;
671  }
672 
676  void inline recordOddSequence (long long idx, long long length, sequence_const_iter it, const edit_t et) {
677  while(idx < length){
678  ses.addSequence(*it, idx, 0, et);
679  ++it;
680  ++idx;
681  ++editDistance;
682  }
683  ses.addSequence(*it, idx, 0, et);
684  ++editDistance;
685  }
686 
690  void inline joinSesVec (sesElemVec& s1, sesElemVec& s2) const {
691  if (!s2.empty()) {
692  for (sesElemVec_iter vit=s2.begin();vit!=s2.end();++vit) {
693  s1.push_back(*vit);
694  }
695  }
696  }
697 
701  bool inline wasSwapped () const {
702  return swapped;
703  }
704 
705  };
706 }
707 
708 #endif // DTL_DIFF_H
Definition: functors.hpp:78
Definition: Diff.hpp:51
static Ses< elem > composeSesFromStream(stream &st)
Definition: Diff.hpp:521
void printUnifiedFormat(stream &out) const
Definition: Diff.hpp:362
bool hugeEnabled() const
Definition: Diff.hpp:153
dtl_typedefs(elem, sequence) sequence A
void disableHuge()
Definition: Diff.hpp:161
comparator cmp
Definition: Diff.hpp:71
editPath path
Definition: Diff.hpp:64
bool isHuge() const
Definition: Diff.hpp:124
void onUnserious()
Definition: Diff.hpp:140
size_t N
Definition: Diff.hpp:57
Diff(const sequence &a, const sequence &b, const comparator &comp)
Definition: Diff.hpp:88
bool editDistanceOnly
Definition: Diff.hpp:69
void printSES(ostream &out=cout) const
Definition: Diff.hpp:323
size_t delta
Definition: Diff.hpp:58
Diff(const sequence &a, const sequence &b, bool deletesFirst)
Definition: Diff.hpp:82
static void printUnifiedFormat(const uniHunkVec &hunks, stream &out)
Definition: Diff.hpp:374
void editDistanceOnlyEnabled()
Definition: Diff.hpp:177
Diff()
Definition: Diff.hpp:75
size_t offset
Definition: Diff.hpp:59
void recordOddSequence(long long idx, long long length, sequence_const_iter it, const edit_t et)
Definition: Diff.hpp:676
void composeUnifiedHunks()
Definition: Diff.hpp:385
long long * fp
Definition: Diff.hpp:60
void disableTrivial()
Definition: Diff.hpp:173
long long ox
Definition: Diff.hpp:72
bool huge
Definition: Diff.hpp:67
sequence patch(const sequence &seq) const
Definition: Diff.hpp:233
void compose()
Definition: Diff.hpp:262
long long getEditDistance() const
Definition: Diff.hpp:103
void init()
Definition: Diff.hpp:549
void offUnserious()
Definition: Diff.hpp:144
size_t M
Definition: Diff.hpp:56
bool wasSwapped() const
Definition: Diff.hpp:701
Ses< elem > ses
Definition: Diff.hpp:63
static void printSES(const Ses< elem > &s, stream &out)
Definition: Diff.hpp:331
sequence B
Definition: Diff.hpp:55
elemVec getLcsVec() const
Definition: Diff.hpp:111
Diff(const sequence &a, const sequence &b, bool deleteFirst, const comparator &comp)
Definition: Diff.hpp:94
void storeSES(storedData &sd) const
Definition: Diff.hpp:353
Lcs< elem > lcs
Definition: Diff.hpp:62
sequence uniPatch(const sequence &seq)
Definition: Diff.hpp:184
editPathCordinates pathCordinates
Definition: Diff.hpp:65
long long oy
Definition: Diff.hpp:73
bool trivial
Definition: Diff.hpp:68
void printSES(stream &out) const
Definition: Diff.hpp:318
void printSES(stream &out) const
Definition: Diff.hpp:344
Lcs< elem > getLcs() const
Definition: Diff.hpp:107
Diff(const sequence &a, const sequence &b)
Definition: Diff.hpp:77
void offHuge()
Definition: Diff.hpp:132
void printUnifiedFormat(ostream &out=cout) const
Definition: Diff.hpp:366
~Diff()
Definition: Diff.hpp:101
bool recordSequence(const editPathCordinates &v)
Definition: Diff.hpp:591
uniHunkVec getUniHunks() const
Definition: Diff.hpp:119
bool trivialEnabled() const
Definition: Diff.hpp:165
void enableTrivial()
Definition: Diff.hpp:169
Ses< elem > getSes() const
Definition: Diff.hpp:115
bool isUnserious() const
Definition: Diff.hpp:136
bool swapped
Definition: Diff.hpp:66
long long snake(const long long &k, const long long &above, const long long &below)
Definition: Diff.hpp:571
static void printUnifiedFormat(const uniHunkVec &hunks, ostream &out=cout)
Definition: Diff.hpp:378
long long editDistance
Definition: Diff.hpp:61
void joinSesVec(sesElemVec &s1, sesElemVec &s2) const
Definition: Diff.hpp:690
uniHunkVec uniHunks
Definition: Diff.hpp:70
static void printSES(const Ses< elem > &s, ostream &out=cout)
Definition: Diff.hpp:336
void enableHuge()
Definition: Diff.hpp:157
void onHuge()
Definition: Diff.hpp:128
void onOnlyEditDistance()
Definition: Diff.hpp:148
Definition: Lcs.hpp:48
Definition: Ses.hpp:48
sesElemVec getSequence() const
Definition: Ses.hpp:119
void addSequence(elem e, long long beforeIdx, long long afterIdx, const edit_t type)
Definition: Ses.hpp:83
Definition: functors.hpp:103
Definition: Diff.hpp:43
int edit_t
Definition: variables.hpp:71
const edit_t SES_ADD
Definition: variables.hpp:74
const long long DTL_CONTEXT_SIZE
Definition: variables.hpp:96
const unsigned long long MAX_CORDINATES_SIZE
Definition: variables.hpp:110
const long long DTL_SEPARATE_SIZE
Definition: variables.hpp:95
const edit_t SES_COMMON
Definition: variables.hpp:73
const edit_t SES_DELETE
Definition: variables.hpp:72
vector< long long > editPath
Definition: variables.hpp:112
vector< P > editPathCordinates
Definition: variables.hpp:113
Definition: variables.hpp:101
long long x
Definition: variables.hpp:102
long long k
Definition: variables.hpp:104
long long y
Definition: variables.hpp:103
Definition: variables.hpp:86
long long afterIdx
Definition: variables.hpp:88
long long beforeIdx
Definition: variables.hpp:87
edit_t type
Definition: variables.hpp:89
Definition: variables.hpp:119
vector< sesElem > change
Definition: variables.hpp:122
long long b
Definition: variables.hpp:120
long long d
Definition: variables.hpp:120
long long inc_dec_count
Definition: variables.hpp:123
long long c
Definition: variables.hpp:120
long long a
Definition: variables.hpp:120
vector< sesElem > common[2]
Definition: variables.hpp:121
#define SES_MARK_DELETE
Definition: variables.hpp:79
#define SES_MARK_ADD
Definition: variables.hpp:81
#define SES_MARK_COMMON
Definition: variables.hpp:80