1717
1818package org .apache .ignite .cdc .conflictresolve ;
1919
20+ import java .util .Objects ;
2021import org .apache .ignite .IgniteLogger ;
2122import org .apache .ignite .binary .BinaryObject ;
23+ import org .apache .ignite .internal .processors .cache .CacheObject ;
24+ import org .apache .ignite .internal .processors .cache .CacheObjectUtils ;
2225import org .apache .ignite .internal .processors .cache .CacheObjectValueContext ;
26+ import org .apache .ignite .internal .processors .cache .GridCacheEntryEx ;
27+ import org .apache .ignite .internal .processors .cache .GridCacheEntryRemovedException ;
2328import org .apache .ignite .internal .processors .cache .version .CacheVersionConflictResolver ;
29+ import org .apache .ignite .internal .processors .cache .version .GridCacheVersion ;
2430import org .apache .ignite .internal .processors .cache .version .GridCacheVersionConflictContext ;
2531import org .apache .ignite .internal .processors .cache .version .GridCacheVersionedEntryEx ;
2632import org .apache .ignite .internal .util .tostring .GridToStringInclude ;
@@ -88,11 +94,12 @@ public CacheVersionConflictResolverImpl(
8894 CacheObjectValueContext ctx ,
8995 GridCacheVersionedEntryEx <K , V > oldEntry ,
9096 GridCacheVersionedEntryEx <K , V > newEntry ,
97+ Object prevStateMeta ,
9198 boolean atomicVerComparator
9299 ) {
93100 GridCacheVersionConflictContext <K , V > res = new GridCacheVersionConflictContext <>(ctx , oldEntry , newEntry );
94101
95- boolean useNew = isUseNew (ctx , oldEntry , newEntry );
102+ boolean useNew = isUseNew (ctx , oldEntry , newEntry , prevStateMeta );
96103
97104 if (log .isDebugEnabled ())
98105 debugResolve (ctx , useNew , oldEntry , newEntry );
@@ -117,7 +124,8 @@ public CacheVersionConflictResolverImpl(
117124 protected <K , V > boolean isUseNew (
118125 CacheObjectValueContext ctx ,
119126 GridCacheVersionedEntryEx <K , V > oldEntry ,
120- GridCacheVersionedEntryEx <K , V > newEntry
127+ GridCacheVersionedEntryEx <K , V > newEntry ,
128+ Object prevStateMeta
121129 ) {
122130 if (newEntry .dataCenterId () == clusterId ) // Update made on the local cluster always win.
123131 return true ;
@@ -139,8 +147,8 @@ protected <K, V> boolean isUseNew(
139147 }
140148
141149 if (conflictResolveFieldEnabled ) {
142- Object oldVal = oldEntry .value (ctx );
143150 Object newVal = newEntry .value (ctx );
151+ Object oldVal = oldEntry .value (ctx );
144152
145153 if (oldVal != null && newVal != null ) {
146154 try {
@@ -153,6 +161,17 @@ protected <K, V> boolean isUseNew(
153161 );
154162 }
155163 }
164+
165+ Object field = oldVal != null ? value (oldVal ) : null ;
166+
167+ if (Objects .equals (field , prevStateMeta )) // Previous value synchronized.
168+ return true ;
169+ }
170+ else {
171+ GridCacheVersion oldVer = oldEntry .value (ctx ) != null ? oldEntry .version () : null ; // TODO null value version (entry vs row)
172+
173+ if (Objects .equals (oldVer , prevStateMeta )) // Previous value synchronized.
174+ return true ;
156175 }
157176
158177 log .error ("Conflict can't be resolved, " + (newEntry .value (ctx ) == null ? "remove" : "update" ) + " ignored " +
@@ -162,6 +181,30 @@ protected <K, V> boolean isUseNew(
162181 return false ;
163182 }
164183
184+ /**
185+ * {@inheritDoc}
186+ */
187+ @ Override public Object previousStateMetadata (GridCacheEntryEx entry ) {
188+ if (conflictResolveFieldEnabled ) {
189+ CacheObjectValueContext ctx = entry .context ().cacheObjectContext ();
190+ CacheObject val = entry .rawGet ();
191+
192+ return val != null ?
193+ value (CacheObjectUtils .unwrapBinaryIfNeeded (ctx , val , true , true , null )) :
194+ null ;
195+ }
196+ else {
197+ try {
198+ GridCacheVersion ver = entry .version ();
199+
200+ return ver != null ? ver .conflictVersion () : null ;
201+ }
202+ catch (GridCacheEntryRemovedException e ) { // TODO
203+ throw new RuntimeException (e );
204+ }
205+ }
206+ }
207+
165208 /** @return Conflict resolve field value. */
166209 protected Comparable value (Object val ) {
167210 return (val instanceof BinaryObject )
0 commit comments