2021-07-24 02:37:17 +00:00
package androidx.recyclerview.widget ;
import androidx.annotation.IntRange ;
import androidx.annotation.NonNull ;
import androidx.annotation.Nullable ;
import androidx.annotation.VisibleForTesting ;
import androidx.recyclerview.widget.RecyclerView ;
import c.d.b.a.a ;
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.Collections ;
import java.util.Comparator ;
import java.util.List ;
public class DiffUtil {
private static final Comparator < Snake > SNAKE_COMPARATOR = new AnonymousClass1 ( ) ;
/* renamed from: androidx.recyclerview.widget.DiffUtil$1 reason: invalid class name */
public static class AnonymousClass1 implements Comparator < Snake > {
public int compare ( Snake snake , Snake snake2 ) {
2021-08-10 10:47:20 +00:00
int i = snake . f27x - snake2 . f27x ;
return i = = 0 ? snake . f28y - snake2 . f28y : i ;
2021-07-24 02:37:17 +00:00
}
}
public static abstract class Callback {
public abstract boolean areContentsTheSame ( int i , int i2 ) ;
public abstract boolean areItemsTheSame ( int i , int i2 ) ;
@Nullable
public Object getChangePayload ( int i , int i2 ) {
return null ;
}
public abstract int getNewListSize ( ) ;
public abstract int getOldListSize ( ) ;
}
public static class DiffResult {
private static final int FLAG_CHANGED = 2 ;
private static final int FLAG_IGNORE = 16 ;
private static final int FLAG_MASK = 31 ;
private static final int FLAG_MOVED_CHANGED = 4 ;
private static final int FLAG_MOVED_NOT_CHANGED = 8 ;
private static final int FLAG_NOT_CHANGED = 1 ;
private static final int FLAG_OFFSET = 5 ;
public static final int NO_POSITION = - 1 ;
private final Callback mCallback ;
private final boolean mDetectMoves ;
private final int [ ] mNewItemStatuses ;
private final int mNewListSize ;
private final int [ ] mOldItemStatuses ;
private final int mOldListSize ;
private final List < Snake > mSnakes ;
public DiffResult ( Callback callback , List < Snake > list , int [ ] iArr , int [ ] iArr2 , boolean z2 ) {
this . mSnakes = list ;
this . mOldItemStatuses = iArr ;
this . mNewItemStatuses = iArr2 ;
Arrays . fill ( iArr , 0 ) ;
Arrays . fill ( iArr2 , 0 ) ;
this . mCallback = callback ;
this . mOldListSize = callback . getOldListSize ( ) ;
this . mNewListSize = callback . getNewListSize ( ) ;
this . mDetectMoves = z2 ;
addRootSnake ( ) ;
findMatchingItems ( ) ;
}
private void addRootSnake ( ) {
Snake snake = this . mSnakes . isEmpty ( ) ? null : this . mSnakes . get ( 0 ) ;
2021-08-10 10:47:20 +00:00
if ( snake = = null | | snake . f27x ! = 0 | | snake . f28y ! = 0 ) {
2021-07-24 02:37:17 +00:00
Snake snake2 = new Snake ( ) ;
2021-08-10 10:47:20 +00:00
snake2 . f27x = 0 ;
snake2 . f28y = 0 ;
2021-07-24 02:37:17 +00:00
snake2 . removal = false ;
snake2 . size = 0 ;
snake2 . reverse = false ;
this . mSnakes . add ( 0 , snake2 ) ;
}
}
private void dispatchAdditions ( List < PostponedUpdate > list , ListUpdateCallback listUpdateCallback , int i , int i2 , int i3 ) {
if ( ! this . mDetectMoves ) {
listUpdateCallback . onInserted ( i , i2 ) ;
return ;
}
for ( int i4 = i2 - 1 ; i4 > = 0 ; i4 - - ) {
int [ ] iArr = this . mNewItemStatuses ;
int i5 = i3 + i4 ;
int i6 = iArr [ i5 ] & 31 ;
if ( i6 = = 0 ) {
listUpdateCallback . onInserted ( i , 1 ) ;
for ( PostponedUpdate postponedUpdate : list ) {
postponedUpdate . currentPos + + ;
}
} else if ( i6 = = 4 | | i6 = = 8 ) {
int i7 = iArr [ i5 ] > > 5 ;
listUpdateCallback . onMoved ( removePostponedUpdate ( list , i7 , true ) . currentPos , i ) ;
if ( i6 = = 4 ) {
listUpdateCallback . onChanged ( i , 1 , this . mCallback . getChangePayload ( i7 , i5 ) ) ;
}
} else if ( i6 = = 16 ) {
list . add ( new PostponedUpdate ( i5 , i , false ) ) ;
} else {
StringBuilder L = a . L ( " unknown flag for pos " , i5 , " " ) ;
L . append ( Long . toBinaryString ( ( long ) i6 ) ) ;
throw new IllegalStateException ( L . toString ( ) ) ;
}
}
}
private void dispatchRemovals ( List < PostponedUpdate > list , ListUpdateCallback listUpdateCallback , int i , int i2 , int i3 ) {
if ( ! this . mDetectMoves ) {
listUpdateCallback . onRemoved ( i , i2 ) ;
return ;
}
for ( int i4 = i2 - 1 ; i4 > = 0 ; i4 - - ) {
int [ ] iArr = this . mOldItemStatuses ;
int i5 = i3 + i4 ;
int i6 = iArr [ i5 ] & 31 ;
if ( i6 = = 0 ) {
listUpdateCallback . onRemoved ( i + i4 , 1 ) ;
for ( PostponedUpdate postponedUpdate : list ) {
postponedUpdate . currentPos - - ;
}
} else if ( i6 = = 4 | | i6 = = 8 ) {
int i7 = iArr [ i5 ] > > 5 ;
PostponedUpdate removePostponedUpdate = removePostponedUpdate ( list , i7 , false ) ;
listUpdateCallback . onMoved ( i + i4 , removePostponedUpdate . currentPos - 1 ) ;
if ( i6 = = 4 ) {
listUpdateCallback . onChanged ( removePostponedUpdate . currentPos - 1 , 1 , this . mCallback . getChangePayload ( i5 , i7 ) ) ;
}
} else if ( i6 = = 16 ) {
list . add ( new PostponedUpdate ( i5 , i + i4 , true ) ) ;
} else {
StringBuilder L = a . L ( " unknown flag for pos " , i5 , " " ) ;
L . append ( Long . toBinaryString ( ( long ) i6 ) ) ;
throw new IllegalStateException ( L . toString ( ) ) ;
}
}
}
private void findAddition ( int i , int i2 , int i3 ) {
if ( this . mOldItemStatuses [ i - 1 ] = = 0 ) {
findMatchingItem ( i , i2 , i3 , false ) ;
}
}
private boolean findMatchingItem ( int i , int i2 , int i3 , boolean z2 ) {
int i4 ;
int i5 ;
if ( z2 ) {
i2 - - ;
i4 = i ;
i5 = i2 ;
} else {
i5 = i - 1 ;
i4 = i5 ;
}
while ( i3 > = 0 ) {
Snake snake = this . mSnakes . get ( i3 ) ;
2021-08-10 10:47:20 +00:00
int i6 = snake . f27x ;
2021-07-24 02:37:17 +00:00
int i7 = snake . size ;
int i8 = i6 + i7 ;
2021-08-10 10:47:20 +00:00
int i9 = snake . f28y + i7 ;
2021-07-24 02:37:17 +00:00
int i10 = 8 ;
if ( z2 ) {
for ( int i11 = i4 - 1 ; i11 > = i8 ; i11 - - ) {
if ( this . mCallback . areItemsTheSame ( i11 , i5 ) ) {
if ( ! this . mCallback . areContentsTheSame ( i11 , i5 ) ) {
i10 = 4 ;
}
this . mNewItemStatuses [ i5 ] = ( i11 < < 5 ) | 16 ;
this . mOldItemStatuses [ i11 ] = ( i5 < < 5 ) | i10 ;
return true ;
}
}
continue ;
} else {
for ( int i12 = i2 - 1 ; i12 > = i9 ; i12 - - ) {
if ( this . mCallback . areItemsTheSame ( i5 , i12 ) ) {
if ( ! this . mCallback . areContentsTheSame ( i5 , i12 ) ) {
i10 = 4 ;
}
int i13 = i - 1 ;
this . mOldItemStatuses [ i13 ] = ( i12 < < 5 ) | 16 ;
this . mNewItemStatuses [ i12 ] = ( i13 < < 5 ) | i10 ;
return true ;
}
}
continue ;
}
2021-08-10 10:47:20 +00:00
i4 = snake . f27x ;
i2 = snake . f28y ;
2021-07-24 02:37:17 +00:00
i3 - - ;
}
return false ;
}
private void findMatchingItems ( ) {
int i = this . mOldListSize ;
int i2 = this . mNewListSize ;
for ( int size = this . mSnakes . size ( ) - 1 ; size > = 0 ; size - - ) {
Snake snake = this . mSnakes . get ( size ) ;
2021-08-10 10:47:20 +00:00
int i3 = snake . f27x ;
2021-07-24 02:37:17 +00:00
int i4 = snake . size ;
int i5 = i3 + i4 ;
2021-08-10 10:47:20 +00:00
int i6 = snake . f28y + i4 ;
2021-07-24 02:37:17 +00:00
if ( this . mDetectMoves ) {
while ( i > i5 ) {
findAddition ( i , i2 , size ) ;
i - - ;
}
while ( i2 > i6 ) {
findRemoval ( i , i2 , size ) ;
i2 - - ;
}
}
for ( int i7 = 0 ; i7 < snake . size ; i7 + + ) {
2021-08-10 10:47:20 +00:00
int i8 = snake . f27x + i7 ;
int i9 = snake . f28y + i7 ;
2021-07-24 02:37:17 +00:00
int i10 = this . mCallback . areContentsTheSame ( i8 , i9 ) ? 1 : 2 ;
this . mOldItemStatuses [ i8 ] = ( i9 < < 5 ) | i10 ;
this . mNewItemStatuses [ i9 ] = ( i8 < < 5 ) | i10 ;
}
2021-08-10 10:47:20 +00:00
i = snake . f27x ;
i2 = snake . f28y ;
2021-07-24 02:37:17 +00:00
}
}
private void findRemoval ( int i , int i2 , int i3 ) {
if ( this . mNewItemStatuses [ i2 - 1 ] = = 0 ) {
findMatchingItem ( i , i2 , i3 , true ) ;
}
}
private static PostponedUpdate removePostponedUpdate ( List < PostponedUpdate > list , int i , boolean z2 ) {
int size = list . size ( ) - 1 ;
while ( size > = 0 ) {
PostponedUpdate postponedUpdate = list . get ( size ) ;
if ( postponedUpdate . posInOwnerList = = i & & postponedUpdate . removal = = z2 ) {
list . remove ( size ) ;
while ( size < list . size ( ) ) {
list . get ( size ) . currentPos + = z2 ? 1 : - 1 ;
size + + ;
}
return postponedUpdate ;
}
size - - ;
}
return null ;
}
public int convertNewPositionToOld ( @IntRange ( from = 0 ) int i ) {
if ( i < 0 | | i > = this . mNewListSize ) {
StringBuilder L = a . L ( " Index out of bounds - passed position = " , i , " , new list size = " ) ;
L . append ( this . mNewListSize ) ;
throw new IndexOutOfBoundsException ( L . toString ( ) ) ;
}
int i2 = this . mNewItemStatuses [ i ] ;
if ( ( i2 & 31 ) = = 0 ) {
return - 1 ;
}
return i2 > > 5 ;
}
public int convertOldPositionToNew ( @IntRange ( from = 0 ) int i ) {
if ( i < 0 | | i > = this . mOldListSize ) {
StringBuilder L = a . L ( " Index out of bounds - passed position = " , i , " , old list size = " ) ;
L . append ( this . mOldListSize ) ;
throw new IndexOutOfBoundsException ( L . toString ( ) ) ;
}
int i2 = this . mOldItemStatuses [ i ] ;
if ( ( i2 & 31 ) = = 0 ) {
return - 1 ;
}
return i2 > > 5 ;
}
public void dispatchUpdatesTo ( @NonNull ListUpdateCallback listUpdateCallback ) {
BatchingListUpdateCallback batchingListUpdateCallback = listUpdateCallback instanceof BatchingListUpdateCallback ? ( BatchingListUpdateCallback ) listUpdateCallback : new BatchingListUpdateCallback ( listUpdateCallback ) ;
List < PostponedUpdate > arrayList = new ArrayList < > ( ) ;
int i = this . mOldListSize ;
int i2 = this . mNewListSize ;
for ( int size = this . mSnakes . size ( ) - 1 ; size > = 0 ; size - - ) {
Snake snake = this . mSnakes . get ( size ) ;
int i3 = snake . size ;
2021-08-10 10:47:20 +00:00
int i4 = snake . f27x + i3 ;
int i5 = snake . f28y + i3 ;
2021-07-24 02:37:17 +00:00
if ( i4 < i ) {
dispatchRemovals ( arrayList , batchingListUpdateCallback , i4 , i - i4 , i4 ) ;
}
if ( i5 < i2 ) {
dispatchAdditions ( arrayList , batchingListUpdateCallback , i4 , i2 - i5 , i5 ) ;
}
for ( int i6 = i3 - 1 ; i6 > = 0 ; i6 - - ) {
int [ ] iArr = this . mOldItemStatuses ;
2021-08-10 10:47:20 +00:00
int i7 = snake . f27x ;
2021-07-24 02:37:17 +00:00
if ( ( iArr [ i7 + i6 ] & 31 ) = = 2 ) {
2021-08-10 10:47:20 +00:00
batchingListUpdateCallback . onChanged ( i7 + i6 , 1 , this . mCallback . getChangePayload ( i7 + i6 , snake . f28y + i6 ) ) ;
2021-07-24 02:37:17 +00:00
}
}
2021-08-10 10:47:20 +00:00
i = snake . f27x ;
i2 = snake . f28y ;
2021-07-24 02:37:17 +00:00
}
batchingListUpdateCallback . dispatchLastEvent ( ) ;
}
public void dispatchUpdatesTo ( @NonNull RecyclerView . Adapter adapter ) {
dispatchUpdatesTo ( new AdapterListUpdateCallback ( adapter ) ) ;
}
@VisibleForTesting
public List < Snake > getSnakes ( ) {
return this . mSnakes ;
}
}
public static abstract class ItemCallback < T > {
public abstract boolean areContentsTheSame ( @NonNull T t , @NonNull T t2 ) ;
public abstract boolean areItemsTheSame ( @NonNull T t , @NonNull T t2 ) ;
@Nullable
public Object getChangePayload ( @NonNull T t , @NonNull T t2 ) {
return null ;
}
}
public static class PostponedUpdate {
public int currentPos ;
public int posInOwnerList ;
public boolean removal ;
public PostponedUpdate ( int i , int i2 , boolean z2 ) {
this . posInOwnerList = i ;
this . currentPos = i2 ;
this . removal = z2 ;
}
}
public static class Range {
public int newListEnd ;
public int newListStart ;
public int oldListEnd ;
public int oldListStart ;
public Range ( ) {
}
public Range ( int i , int i2 , int i3 , int i4 ) {
this . oldListStart = i ;
this . oldListEnd = i2 ;
this . newListStart = i3 ;
this . newListEnd = i4 ;
}
}
public static class Snake {
public boolean removal ;
public boolean reverse ;
public int size ;
/* renamed from: x reason: collision with root package name */
2021-08-10 10:47:20 +00:00
public int f27x ;
2021-07-24 02:37:17 +00:00
/* renamed from: y reason: collision with root package name */
2021-08-10 10:47:20 +00:00
public int f28y ;
2021-07-24 02:37:17 +00:00
}
private DiffUtil ( ) {
}
@NonNull
public static DiffResult calculateDiff ( @NonNull Callback callback ) {
return calculateDiff ( callback , true ) ;
}
@NonNull
public static DiffResult calculateDiff ( @NonNull Callback callback , boolean z2 ) {
int oldListSize = callback . getOldListSize ( ) ;
int newListSize = callback . getNewListSize ( ) ;
ArrayList arrayList = new ArrayList ( ) ;
ArrayList arrayList2 = new ArrayList ( ) ;
arrayList2 . add ( new Range ( 0 , oldListSize , 0 , newListSize ) ) ;
int abs = Math . abs ( oldListSize - newListSize ) + oldListSize + newListSize ;
int i = abs * 2 ;
int [ ] iArr = new int [ i ] ;
int [ ] iArr2 = new int [ i ] ;
ArrayList arrayList3 = new ArrayList ( ) ;
while ( ! arrayList2 . isEmpty ( ) ) {
Range range = ( Range ) arrayList2 . remove ( arrayList2 . size ( ) - 1 ) ;
Snake diffPartial = diffPartial ( callback , range . oldListStart , range . oldListEnd , range . newListStart , range . newListEnd , iArr , iArr2 , abs ) ;
if ( diffPartial ! = null ) {
if ( diffPartial . size > 0 ) {
arrayList . add ( diffPartial ) ;
}
2021-08-10 10:47:20 +00:00
diffPartial . f27x + = range . oldListStart ;
diffPartial . f28y + = range . newListStart ;
2021-07-24 02:37:17 +00:00
Range range2 = arrayList3 . isEmpty ( ) ? new Range ( ) : ( Range ) arrayList3 . remove ( arrayList3 . size ( ) - 1 ) ;
range2 . oldListStart = range . oldListStart ;
range2 . newListStart = range . newListStart ;
if ( diffPartial . reverse ) {
2021-08-10 10:47:20 +00:00
range2 . oldListEnd = diffPartial . f27x ;
range2 . newListEnd = diffPartial . f28y ;
2021-07-24 02:37:17 +00:00
} else if ( diffPartial . removal ) {
2021-08-10 10:47:20 +00:00
range2 . oldListEnd = diffPartial . f27x - 1 ;
range2 . newListEnd = diffPartial . f28y ;
2021-07-24 02:37:17 +00:00
} else {
2021-08-10 10:47:20 +00:00
range2 . oldListEnd = diffPartial . f27x ;
range2 . newListEnd = diffPartial . f28y - 1 ;
2021-07-24 02:37:17 +00:00
}
arrayList2 . add ( range2 ) ;
if ( ! diffPartial . reverse ) {
2021-08-10 10:47:20 +00:00
int i2 = diffPartial . f27x ;
2021-07-24 02:37:17 +00:00
int i3 = diffPartial . size ;
range . oldListStart = i2 + i3 ;
2021-08-10 10:47:20 +00:00
range . newListStart = diffPartial . f28y + i3 ;
2021-07-24 02:37:17 +00:00
} else if ( diffPartial . removal ) {
2021-08-10 10:47:20 +00:00
int i4 = diffPartial . f27x ;
2021-07-24 02:37:17 +00:00
int i5 = diffPartial . size ;
range . oldListStart = i4 + i5 + 1 ;
2021-08-10 10:47:20 +00:00
range . newListStart = diffPartial . f28y + i5 ;
2021-07-24 02:37:17 +00:00
} else {
2021-08-10 10:47:20 +00:00
int i6 = diffPartial . f27x ;
2021-07-24 02:37:17 +00:00
int i7 = diffPartial . size ;
range . oldListStart = i6 + i7 ;
2021-08-10 10:47:20 +00:00
range . newListStart = diffPartial . f28y + i7 + 1 ;
2021-07-24 02:37:17 +00:00
}
arrayList2 . add ( range ) ;
} else {
arrayList3 . add ( range ) ;
}
}
Collections . sort ( arrayList , SNAKE_COMPARATOR ) ;
return new DiffResult ( callback , arrayList , iArr , iArr2 , z2 ) ;
}
/ * JADX WARNING : Code restructure failed : missing block : B : 14 : 0x0042 , code lost :
if ( r24 [ r13 - 1 ] < r24 [ r13 + r5 ] ) goto L_0x004d ;
* /
/ * JADX WARNING : Code restructure failed : missing block : B : 41 : 0x00b8 , code lost :
if ( r25 [ r12 - 1 ] < r25 [ r12 + 1 ] ) goto L_0x00c5 ;
* /
private static Snake diffPartial ( Callback callback , int i , int i2 , int i3 , int i4 , int [ ] iArr , int [ ] iArr2 , int i5 ) {
boolean z2 ;
int i6 ;
int i7 ;
int i8 ;
int i9 ;
boolean z3 ;
int i10 ;
int i11 ;
int i12 = i2 - i ;
int i13 = i4 - i3 ;
int i14 = 1 ;
if ( i12 < 1 | | i13 < 1 ) {
return null ;
}
int i15 = i12 - i13 ;
int i16 = ( ( i12 + i13 ) + 1 ) / 2 ;
int i17 = ( i5 - i16 ) - 1 ;
int i18 = i5 + i16 + 1 ;
Arrays . fill ( iArr , i17 , i18 , 0 ) ;
Arrays . fill ( iArr2 , i17 + i15 , i18 + i15 , i12 ) ;
boolean z4 = i15 % 2 ! = 0 ;
int i19 = 0 ;
while ( i19 < = i16 ) {
int i20 = - i19 ;
int i21 = i20 ;
while ( i21 < = i19 ) {
if ( i21 ! = i20 ) {
if ( i21 ! = i19 ) {
int i22 = i5 + i21 ;
}
i10 = iArr [ ( i5 + i21 ) - i14 ] + i14 ;
z3 = true ;
i11 = i10 - i21 ;
while ( i10 < i12 & & i11 < i13 & & callback . areItemsTheSame ( i + i10 , i3 + i11 ) ) {
i10 + + ;
i11 + + ;
}
int i23 = i5 + i21 ;
iArr [ i23 ] = i10 ;
if ( z4 | | i21 < ( i15 - i19 ) + 1 | | i21 > ( i15 + i19 ) - 1 | | iArr [ i23 ] < iArr2 [ i23 ] ) {
i21 + = 2 ;
i14 = 1 ;
} else {
Snake snake = new Snake ( ) ;
int i24 = iArr2 [ i23 ] ;
2021-08-10 10:47:20 +00:00
snake . f27x = i24 ;
snake . f28y = i24 - i21 ;
2021-07-24 02:37:17 +00:00
snake . size = iArr [ i23 ] - iArr2 [ i23 ] ;
snake . removal = z3 ;
snake . reverse = false ;
return snake ;
}
}
i10 = iArr [ i5 + i21 + i14 ] ;
z3 = false ;
i11 = i10 - i21 ;
while ( i10 < i12 ) {
i10 + + ;
i11 + + ;
}
int i23 = i5 + i21 ;
iArr [ i23 ] = i10 ;
if ( z4 ) {
}
i21 + = 2 ;
i14 = 1 ;
}
int i25 = i20 ;
while ( i25 < = i19 ) {
int i26 = i25 + i15 ;
if ( i26 ! = i19 + i15 ) {
if ( i26 ! = i20 + i15 ) {
int i27 = i5 + i26 ;
i9 = 1 ;
} else {
i9 = 1 ;
}
i6 = iArr2 [ ( i5 + i26 ) + i9 ] - i9 ;
z2 = true ;
i7 = i6 - i26 ;
while ( true ) {
if ( i6 > 0 & & i7 > 0 ) {
i8 = i12 ;
if ( ! callback . areItemsTheSame ( ( i + i6 ) - 1 , ( i3 + i7 ) - 1 ) ) {
break ;
}
i6 - - ;
i7 - - ;
i12 = i8 ;
} else {
break ;
}
}
i8 = i12 ;
int i28 = i5 + i26 ;
iArr2 [ i28 ] = i6 ;
if ( ! z4 | | i26 < i20 | | i26 > i19 | | iArr [ i28 ] < iArr2 [ i28 ] ) {
i25 + = 2 ;
i12 = i8 ;
} else {
Snake snake2 = new Snake ( ) ;
int i29 = iArr2 [ i28 ] ;
2021-08-10 10:47:20 +00:00
snake2 . f27x = i29 ;
snake2 . f28y = i29 - i26 ;
2021-07-24 02:37:17 +00:00
snake2 . size = iArr [ i28 ] - iArr2 [ i28 ] ;
snake2 . removal = z2 ;
snake2 . reverse = true ;
return snake2 ;
}
} else {
i9 = 1 ;
}
i6 = iArr2 [ ( i5 + i26 ) - i9 ] ;
z2 = false ;
i7 = i6 - i26 ;
while ( true ) {
if ( i6 > 0 ) {
break ;
}
break ;
i6 - - ;
i7 - - ;
i12 = i8 ;
}
i8 = i12 ;
int i28 = i5 + i26 ;
iArr2 [ i28 ] = i6 ;
if ( ! z4 ) {
}
i25 + = 2 ;
i12 = i8 ;
}
i19 + + ;
i12 = i12 ;
i14 = 1 ;
}
throw new IllegalStateException ( " DiffUtil hit an unexpected case while trying to calculate the optimal path. Please make sure your data is not changing during the diff calculation. " ) ;
}
}