HHH-9985 - bytecode enhancer - fix merge use case

This commit is contained in:
barreiro 2015-07-25 06:26:40 +01:00 committed by Steve Ebersole
parent 463decd245
commit f759c152e2
11 changed files with 121 additions and 36 deletions

View File

@ -18,7 +18,8 @@ import javassist.Modifier;
import javassist.NotFoundException; import javassist.NotFoundException;
import org.hibernate.bytecode.enhance.internal.tracker.CollectionTracker; import org.hibernate.bytecode.enhance.internal.tracker.CollectionTracker;
import org.hibernate.bytecode.enhance.internal.tracker.SimpleDirtyTracker; import org.hibernate.bytecode.enhance.internal.tracker.DirtyTracker;
import org.hibernate.bytecode.enhance.internal.tracker.SimpleFieldTracker;
import org.hibernate.bytecode.enhance.spi.EnhancementContext; import org.hibernate.bytecode.enhance.spi.EnhancementContext;
import org.hibernate.bytecode.enhance.spi.EnhancementException; import org.hibernate.bytecode.enhance.spi.EnhancementException;
import org.hibernate.bytecode.enhance.spi.Enhancer; import org.hibernate.bytecode.enhance.spi.Enhancer;
@ -36,8 +37,8 @@ public class EntityEnhancer extends Enhancer {
super( context ); super( context );
} }
// for very small sizes SimpleDirtyTracker implementation ends up being faster // assuming the number of fields is not very high, SimpleFieldTracker implementation it's the fastest
private static final String TRACKER_IMPL = SimpleDirtyTracker.class.getName(); private static final String DIRTY_TRACKER_IMPL = SimpleFieldTracker.class.getName();
public void enhance(CtClass managedCtClass) { public void enhance(CtClass managedCtClass) {
// add the ManagedEntity interface // add the ManagedEntity interface
@ -107,7 +108,11 @@ public class EntityEnhancer extends Enhancer {
try { try {
managedCtClass.addInterface( classPool.get( SelfDirtinessTracker.class.getName() ) ); managedCtClass.addInterface( classPool.get( SelfDirtinessTracker.class.getName() ) );
FieldWriter.addField( managedCtClass, classPool.get( TRACKER_IMPL ), EnhancerConstants.TRACKER_FIELD_NAME ); FieldWriter.addField(
managedCtClass,
classPool.get( DIRTY_TRACKER_IMPL ),
EnhancerConstants.TRACKER_FIELD_NAME
);
FieldWriter.addField( FieldWriter.addField(
managedCtClass, managedCtClass,
classPool.get( CollectionTracker.class.getName() ), classPool.get( CollectionTracker.class.getName() ),
@ -124,14 +129,14 @@ public class EntityEnhancer extends Enhancer {
private void createDirtyTrackerMethods(CtClass managedCtClass) { private void createDirtyTrackerMethods(CtClass managedCtClass) {
try { try {
MethodWriter.write( MethodWriter.write(
managedCtClass, "" + managedCtClass,
"public void %1$s(String name) {%n" + "public void %1$s(String name) {%n" +
" if (%2$s == null) { %2$s = new %3$s(); }%n" + " if (%2$s == null) { %2$s = new %3$s(); }%n" +
" %2$s.add(name);%n" + " %2$s.add(name);%n" +
"}", "}",
EnhancerConstants.TRACKER_CHANGER_NAME, EnhancerConstants.TRACKER_CHANGER_NAME,
EnhancerConstants.TRACKER_FIELD_NAME, EnhancerConstants.TRACKER_FIELD_NAME,
TRACKER_IMPL DIRTY_TRACKER_IMPL
); );
createCollectionDirtyCheckMethod( managedCtClass ); createCollectionDirtyCheckMethod( managedCtClass );
@ -139,7 +144,7 @@ public class EntityEnhancer extends Enhancer {
createClearDirtyCollectionMethod( managedCtClass ); createClearDirtyCollectionMethod( managedCtClass );
MethodWriter.write( MethodWriter.write(
managedCtClass, "" + managedCtClass,
"public String[] %1$s() {%n" + "public String[] %1$s() {%n" +
" if(%3$s == null) {%n" + " if(%3$s == null) {%n" +
" return (%2$s == null) ? new String[0] : %2$s.get();%n" + " return (%2$s == null) ? new String[0] : %2$s.get();%n" +
@ -153,12 +158,11 @@ public class EntityEnhancer extends Enhancer {
EnhancerConstants.TRACKER_FIELD_NAME, EnhancerConstants.TRACKER_FIELD_NAME,
EnhancerConstants.TRACKER_COLLECTION_NAME, EnhancerConstants.TRACKER_COLLECTION_NAME,
EnhancerConstants.TRACKER_COLLECTION_CHANGED_FIELD_NAME, EnhancerConstants.TRACKER_COLLECTION_CHANGED_FIELD_NAME,
TRACKER_IMPL DIRTY_TRACKER_IMPL
); );
MethodWriter.write( MethodWriter.write(
managedCtClass, managedCtClass,
"" +
"public boolean %1$s() {%n" + "public boolean %1$s() {%n" +
" return (%2$s != null && !%2$s.isEmpty()) || %3$s();%n" + " return (%2$s != null && !%2$s.isEmpty()) || %3$s();%n" +
"}", "}",
@ -169,7 +173,6 @@ public class EntityEnhancer extends Enhancer {
MethodWriter.write( MethodWriter.write(
managedCtClass, managedCtClass,
"" +
"public void %1$s() {%n" + "public void %1$s() {%n" +
" if (%2$s != null) { %2$s.clear(); }%n" + " if (%2$s != null) { %2$s.clear(); }%n" +
" %3$s();%n" + " %3$s();%n" +
@ -213,7 +216,6 @@ public class EntityEnhancer extends Enhancer {
body.append( body.append(
String.format( String.format(
"" +
"private boolean %1$s() {%n" + "private boolean %1$s() {%n" +
" if (%2$s == null) {%n" + " if (%2$s == null) {%n" +
" return false;%n" + " return false;%n" +
@ -227,7 +229,6 @@ public class EntityEnhancer extends Enhancer {
if ( !enhancementContext.isMappedCollection( ctField ) ) { if ( !enhancementContext.isMappedCollection( ctField ) ) {
body.append( body.append(
String.format( String.format(
"" +
" // collection field [%1$s]%n" + " // collection field [%1$s]%n" +
" if (%1$s == null && %2$s.getSize(\"%1$s\") != -1) { return true; }%n" + " if (%1$s == null && %2$s.getSize(\"%1$s\") != -1) { return true; }%n" +
" if (%1$s != null && %2$s.getSize(\"%1$s\") != %1$s.size()) { return true; }%n", " if (%1$s != null && %2$s.getSize(\"%1$s\") != %1$s.size()) { return true; }%n",
@ -252,12 +253,11 @@ public class EntityEnhancer extends Enhancer {
body.append( body.append(
String.format( String.format(
"" +
"private void %1$s(%3$s tracker) {%n" + "private void %1$s(%3$s tracker) {%n" +
" if (%2$s == null) { return; }%n", " if (%2$s == null) { return; }%n",
EnhancerConstants.TRACKER_COLLECTION_CHANGED_FIELD_NAME, EnhancerConstants.TRACKER_COLLECTION_CHANGED_FIELD_NAME,
EnhancerConstants.TRACKER_COLLECTION_NAME, EnhancerConstants.TRACKER_COLLECTION_NAME,
TRACKER_IMPL DirtyTracker.class.getName()
) )
); );
@ -265,7 +265,6 @@ public class EntityEnhancer extends Enhancer {
if ( !enhancementContext.isMappedCollection( ctField ) ) { if ( !enhancementContext.isMappedCollection( ctField ) ) {
body.append( body.append(
String.format( String.format(
"" +
" // Collection field [%1$s]%n" + " // Collection field [%1$s]%n" +
" if (%1$s == null && %2$s.getSize(\"%1$s\") != -1) { tracker.add(\"%1$s\"); }%n" + " if (%1$s == null && %2$s.getSize(\"%1$s\") != -1) { tracker.add(\"%1$s\"); }%n" +
" if (%1$s != null && %2$s.getSize(\"%1$s\") != %1$s.size()) { tracker.add(\"%1$s\"); }%n", " if (%1$s != null && %2$s.getSize(\"%1$s\") != %1$s.size()) { tracker.add(\"%1$s\"); }%n",
@ -290,7 +289,6 @@ public class EntityEnhancer extends Enhancer {
body.append( body.append(
String.format( String.format(
"" +
"private void %1$s() {%n" + "private void %1$s() {%n" +
" if (%2$s == null) { %2$s = new %3$s(); }%n", " if (%2$s == null) { %2$s = new %3$s(); }%n",
EnhancerConstants.TRACKER_COLLECTION_CLEAR_NAME, EnhancerConstants.TRACKER_COLLECTION_CLEAR_NAME,
@ -303,7 +301,6 @@ public class EntityEnhancer extends Enhancer {
if ( !enhancementContext.isMappedCollection( ctField ) ) { if ( !enhancementContext.isMappedCollection( ctField ) ) {
body.append( body.append(
String.format( String.format(
"" +
" // Collection field [%1$s]%n" + " // Collection field [%1$s]%n" +
" if (%1$s == null) { %2$s.add(\"%1$s\", -1); }%n" + " if (%1$s == null) { %2$s.add(\"%1$s\", -1); }%n" +
" else { %2$s.add(\"%1$s\", %1$s.size()); }%n", " else { %2$s.add(\"%1$s\", %1$s.size()); }%n",

View File

@ -0,0 +1,25 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.bytecode.enhance.internal.tracker;
/**
* Interface to be implemented by dirty trackers, a simplified Set of String.
*
* @author <a href="mailto:lbarreiro@redhat.com">Luis Barreiro</a>
*/
public interface DirtyTracker {
void add(String name);
boolean contains(String name);
void clear();
boolean isEmpty();
String[] get();
}

View File

@ -16,14 +16,15 @@ import java.util.Arrays;
* *
* @author <a href="mailto:lbarreiro@redhat.com">Luis Barreiro</a> * @author <a href="mailto:lbarreiro@redhat.com">Luis Barreiro</a>
*/ */
public final class SimpleDirtyTracker { public final class SimpleFieldTracker implements DirtyTracker {
private String[] names; private String[] names;
public SimpleDirtyTracker() { public SimpleFieldTracker() {
names = new String[0]; names = new String[0];
} }
@Override
public void add(String name) { public void add(String name) {
if ( !contains( name ) ) { if ( !contains( name ) ) {
names = Arrays.copyOf( names, names.length + 1 ); names = Arrays.copyOf( names, names.length + 1 );
@ -31,6 +32,7 @@ public final class SimpleDirtyTracker {
} }
} }
@Override
public boolean contains(String name) { public boolean contains(String name) {
for ( String existing : names ) { for ( String existing : names ) {
if ( existing.equals( name ) ) { if ( existing.equals( name ) ) {
@ -40,14 +42,17 @@ public final class SimpleDirtyTracker {
return false; return false;
} }
@Override
public void clear() { public void clear() {
names = new String[0]; names = new String[0];
} }
@Override
public boolean isEmpty() { public boolean isEmpty() {
return names.length == 0; return names.length == 0;
} }
@Override
public String[] get() { public String[] get() {
return names; return names;
} }

View File

@ -13,14 +13,15 @@ package org.hibernate.bytecode.enhance.internal.tracker;
* *
* @author <a href="mailto:lbarreiro@redhat.com">Luis Barreiro</a> * @author <a href="mailto:lbarreiro@redhat.com">Luis Barreiro</a>
*/ */
public final class SortedDirtyTracker { public final class SortedFieldTracker implements DirtyTracker {
private String[] names; private String[] names;
public SortedDirtyTracker() { public SortedFieldTracker() {
names = new String[0]; names = new String[0];
} }
@Override
public void add(String name) { public void add(String name) {
// we do a binary search: even if we don't find the name at least we get the position to insert into the array // we do a binary search: even if we don't find the name at least we get the position to insert into the array
int insert = 0; int insert = 0;
@ -41,12 +42,13 @@ public final class SortedDirtyTracker {
} }
} }
final String[] newNames = new String[names.length + 1]; final String[] newNames = new String[names.length + 1];
System.arraycopy( names, 0, newNames, 0, insert); System.arraycopy( names, 0, newNames, 0, insert );
System.arraycopy( names, insert, newNames, insert + 1, names.length - insert); System.arraycopy( names, insert, newNames, insert + 1, names.length - insert );
newNames[insert] = name; newNames[insert] = name;
names = newNames; names = newNames;
} }
@Override
public boolean contains(String name) { public boolean contains(String name) {
for ( int low = 0, high = names.length - 1; low <= high; ) { for ( int low = 0, high = names.length - 1; low <= high; ) {
final int middle = low + ( ( high - low ) / 2 ); final int middle = low + ( ( high - low ) / 2 );
@ -66,14 +68,17 @@ public final class SortedDirtyTracker {
return false; return false;
} }
@Override
public void clear() { public void clear() {
names = new String[0]; names = new String[0];
} }
@Override
public boolean isEmpty() { public boolean isEmpty() {
return names.length == 0; return names.length == 0;
} }
@Override
public String[] get() { public String[] get() {
return names; return names;
} }

View File

@ -11,7 +11,8 @@ package org.hibernate.bytecode.enhance.spi;
* *
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class EnhancerConstants { public final class EnhancerConstants {
/** /**
* Prefix for persistent-field reader methods. * Prefix for persistent-field reader methods.
*/ */
@ -141,22 +142,34 @@ public class EnhancerConstants {
*/ */
public static final String TRACKER_COLLECTION_CHANGED_NAME = "$$_hibernate_areCollectionFieldsDirty"; public static final String TRACKER_COLLECTION_CHANGED_NAME = "$$_hibernate_areCollectionFieldsDirty";
/**
* Name of the field that holds the collection tracker
*/
public static final String TRACKER_COLLECTION_NAME = "$$_hibernate_collectionTracker"; public static final String TRACKER_COLLECTION_NAME = "$$_hibernate_collectionTracker";
/** /**
* Name of method to get dirty collection field names * Name of method to get dirty collection field names
*/ */
public static final String TRACKER_COLLECTION_CHANGED_FIELD_NAME = "$$_hibernate_getCollectionFieldDirtyNames"; public static final String TRACKER_COLLECTION_CHANGED_FIELD_NAME = "$$_hibernate_getCollectionFieldDirtyNames";
/**
* Name of method to clear dirty attribute on collection fields
*/
public static final String TRACKER_COLLECTION_CLEAR_NAME = "$$_hibernate_clearDirtyCollectionNames"; public static final String TRACKER_COLLECTION_CLEAR_NAME = "$$_hibernate_clearDirtyCollectionNames";
public static final String TRACKER_COMPOSITE_DIRTY_CHECK = "$$_hibernate_areCompositeFieldsDirty"; /**
* Field to hold the track the owner of the embeddable entity
public static final String TRACKER_COMPOSITE_DIRTY_FIELDS_GETTER = "$$_hibernate_getCompositeDirtyFields"; */
public static final String TRACKER_COMPOSITE_FIELD_NAME = "$$_hibernate_compositeOwners"; public static final String TRACKER_COMPOSITE_FIELD_NAME = "$$_hibernate_compositeOwners";
/**
* Method to set the owner of the embedded entity
*/
public static final String TRACKER_COMPOSITE_SET_OWNER = "$$_hibernate_setOwner"; public static final String TRACKER_COMPOSITE_SET_OWNER = "$$_hibernate_setOwner";
/**
* Method to clear the owner of the embedded entity
*/
public static final String TRACKER_COMPOSITE_CLEAR_OWNER = "$$_hibernate_clearOwner"; public static final String TRACKER_COMPOSITE_CLEAR_OWNER = "$$_hibernate_clearOwner";
private EnhancerConstants() { private EnhancerConstants() {

View File

@ -10,7 +10,7 @@ package org.hibernate.bytecode.enhance.spi.interceptor;
import java.util.Set; import java.util.Set;
import org.hibernate.LazyInitializationException; import org.hibernate.LazyInitializationException;
import org.hibernate.bytecode.enhance.internal.tracker.SimpleDirtyTracker; import org.hibernate.bytecode.enhance.internal.tracker.SimpleFieldTracker;
import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer; import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer;
import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
@ -26,7 +26,7 @@ public class LazyAttributeLoader implements PersistentAttributeInterceptor {
private final Set<String> lazyFields; private final Set<String> lazyFields;
private final String entityName; private final String entityName;
private final SimpleDirtyTracker initializedFields = new SimpleDirtyTracker(); private final SimpleFieldTracker initializedFields = new SimpleFieldTracker();
public LazyAttributeLoader(SessionImplementor session, Set<String> lazyFields, String entityName) { public LazyAttributeLoader(SessionImplementor session, Set<String> lazyFields, String entityName) {
this.session = session; this.session = session;
@ -58,6 +58,14 @@ public class LazyAttributeLoader implements PersistentAttributeInterceptor {
} }
} }
public void setLoaded(String attributeName) {
initializedFields.add( attributeName );
}
public String[] getiInitializedFields() {
return initializedFields.get();
}
@Override @Override
public String toString() { public String toString() {
return "LazyAttributeLoader(entityName=" + entityName + " ,lazyFields=" + lazyFields + ')'; return "LazyAttributeLoader(entityName=" + entityName + " ,lazyFields=" + lazyFields + ')';

View File

@ -287,7 +287,7 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
} }
if( entity instanceof SelfDirtinessTracker ) { if( entity instanceof SelfDirtinessTracker ) {
((SelfDirtinessTracker) entity).$$_hibernate_clearDirtyAttributes(); ( (SelfDirtinessTracker) entity ).$$_hibernate_clearDirtyAttributes();
} }
persistenceContext.getSession() persistenceContext.getSession()
@ -342,7 +342,7 @@ public abstract class AbstractEntityEntry implements Serializable, EntityEntry {
private boolean isUnequivocallyNonDirty(Object entity) { private boolean isUnequivocallyNonDirty(Object entity) {
if(entity instanceof SelfDirtinessTracker) { if(entity instanceof SelfDirtinessTracker) {
return ((SelfDirtinessTracker) entity).$$_hibernate_hasDirtyAttributes(); return ! ( (SelfDirtinessTracker) entity ).$$_hibernate_hasDirtyAttributes();
} }
final CustomEntityDirtinessStrategy customEntityDirtinessStrategy = final CustomEntityDirtinessStrategy customEntityDirtinessStrategy =

View File

@ -32,6 +32,11 @@ public interface SelfDirtinessTracker {
*/ */
String[] $$_hibernate_getDirtyAttributes(); String[] $$_hibernate_getDirtyAttributes();
/**
* Adds persistent attribute to the set of values that have changed
*/
void $$_hibernate_trackChange(String attributes);
/** /**
* Clear the stored dirty attributes * Clear the stored dirty attributes
*/ */

View File

@ -15,6 +15,7 @@ import org.hibernate.ObjectDeletedException;
import org.hibernate.StaleObjectStateException; import org.hibernate.StaleObjectStateException;
import org.hibernate.WrongClassException; import org.hibernate.WrongClassException;
import org.hibernate.boot.registry.selector.spi.StrategySelector; import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoader;
import org.hibernate.bytecode.instrumentation.spi.FieldInterceptor; import org.hibernate.bytecode.instrumentation.spi.FieldInterceptor;
import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.internal.Cascade; import org.hibernate.engine.internal.Cascade;
@ -23,6 +24,9 @@ import org.hibernate.engine.spi.CascadingAction;
import org.hibernate.engine.spi.CascadingActions; import org.hibernate.engine.spi.CascadingActions;
import org.hibernate.engine.spi.EntityEntry; import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistentAttributeInterceptable;
import org.hibernate.engine.spi.PersistentAttributeInterceptor;
import org.hibernate.engine.spi.SelfDirtinessTracker;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.event.spi.EntityCopyObserver; import org.hibernate.event.spi.EntityCopyObserver;
@ -341,6 +345,27 @@ public class DefaultMergeEventListener extends AbstractSaveEventListener impleme
interceptor.dirty(); interceptor.dirty();
} }
} }
// for enhanced entities, copy over the dirty attributes and the lazy/loaded fields in the interceptor
if ( entity instanceof SelfDirtinessTracker && target instanceof SelfDirtinessTracker ) {
for ( String fieldName : ( (SelfDirtinessTracker) entity ).$$_hibernate_getDirtyAttributes() ) {
( (SelfDirtinessTracker) target ).$$_hibernate_trackChange( fieldName );
}
}
if ( entity instanceof PersistentAttributeInterceptable
&& target instanceof PersistentAttributeInterceptable
&& ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor() != null
&& ( (PersistentAttributeInterceptable) target ).$$_hibernate_getInterceptor() != null ) {
PersistentAttributeInterceptor entityInterceptor = ( (PersistentAttributeInterceptable) entity ).$$_hibernate_getInterceptor();
PersistentAttributeInterceptor targetInterceptor = ( (PersistentAttributeInterceptable) target ).$$_hibernate_getInterceptor();
if ( entityInterceptor instanceof LazyAttributeLoader && targetInterceptor instanceof LazyAttributeLoader ) {
for ( String fieldName : ( (LazyAttributeLoader) entityInterceptor ).getiInitializedFields() ) {
( (LazyAttributeLoader) targetInterceptor ).setLoaded( fieldName );
}
}
}
} }
private boolean isVersionChanged(Object entity, EventSource source, EntityPersister persister, Object target) { private boolean isVersionChanged(Object entity, EventSource source, EntityPersister persister, Object target) {

View File

@ -98,6 +98,7 @@ public abstract class DecompileUtils {
} }
if ( interfaceNames.contains( SelfDirtinessTracker.class.getName() ) ) { if ( interfaceNames.contains( SelfDirtinessTracker.class.getName() ) ) {
assertTrue( fieldNames.contains( EnhancerConstants.TRACKER_FIELD_NAME ) ); assertTrue( fieldNames.contains( EnhancerConstants.TRACKER_FIELD_NAME ) );
assertTrue( methodNames.contains( EnhancerConstants.TRACKER_CHANGER_NAME ) );
assertTrue( methodNames.contains( EnhancerConstants.TRACKER_GET_NAME ) ); assertTrue( methodNames.contains( EnhancerConstants.TRACKER_GET_NAME ) );
assertTrue( methodNames.contains( EnhancerConstants.TRACKER_CLEAR_NAME ) ); assertTrue( methodNames.contains( EnhancerConstants.TRACKER_CLEAR_NAME ) );
assertTrue( methodNames.contains( EnhancerConstants.TRACKER_HAS_CHANGED_NAME ) ); assertTrue( methodNames.contains( EnhancerConstants.TRACKER_HAS_CHANGED_NAME ) );

View File

@ -6,8 +6,9 @@
*/ */
package org.hibernate.test.bytecode.enhancement.tracker; package org.hibernate.test.bytecode.enhancement.tracker;
import org.hibernate.bytecode.enhance.internal.tracker.SimpleDirtyTracker; import org.hibernate.bytecode.enhance.internal.tracker.DirtyTracker;
import org.hibernate.bytecode.enhance.internal.tracker.SortedDirtyTracker; import org.hibernate.bytecode.enhance.internal.tracker.SimpleFieldTracker;
import org.hibernate.bytecode.enhance.internal.tracker.SortedFieldTracker;
import org.junit.Test; import org.junit.Test;
@ -22,7 +23,7 @@ public class DirtyTrackerTest {
@Test @Test
public void testSimpleTracker() { public void testSimpleTracker() {
SimpleDirtyTracker tracker = new SimpleDirtyTracker(); DirtyTracker tracker = new SimpleFieldTracker();
assertTrue(tracker.isEmpty()); assertTrue(tracker.isEmpty());
assertTrue(tracker.get().length == 0); assertTrue(tracker.get().length == 0);
@ -46,7 +47,7 @@ public class DirtyTrackerTest {
@Test @Test
public void testSortedTracker() { public void testSortedTracker() {
SortedDirtyTracker tracker = new SortedDirtyTracker(); DirtyTracker tracker = new SortedFieldTracker();
assertTrue(tracker.isEmpty()); assertTrue(tracker.isEmpty());
assertTrue(tracker.get().length == 0); assertTrue(tracker.get().length == 0);