Add MutableValueNext to replace mutableContent such that hash compute is only done once

Adds MutableValueInfo.nextDirty() to replace the isEqualToJson() method. The next is computed once and stored. BindablePropertyJsonUpdate makes the .mutableNext(propertyIndex) call to move the next MutableValueInfo and return the json content.
This commit is contained in:
rbygrave
2021-07-29 15:42:16 +12:00
parent 0d8e7c852b
commit c66d248e96
5 changed files with 125 additions and 47 deletions
@@ -105,7 +105,7 @@ public final class EntityBeanIntercept implements Serializable {
* Holds json content determined at point of dirty check.
* Stored here on dirty check such that we only convert to json once.
*/
private String[] mutableContent;
private MutableValueNext[] mutableNext;
/**
* Create a intercept with a given entity.
@@ -395,7 +395,7 @@ public final class EntityBeanIntercept implements Serializable {
this.owner._ebean_setEmbeddedLoaded();
this.lazyLoadProperty = -1;
this.origValues = null;
this.mutableContent = null;
this.mutableNext = null;
for (int i = 0; i < flags.length; i++) {
flags[i] &= ~(FLAG_CHANGED_PROP | FLAG_ORIG_VALUE_SET);
}
@@ -1203,23 +1203,29 @@ public final class EntityBeanIntercept implements Serializable {
}
/**
* Return the [json] content of a mutable value.
*/
public String mutableContent(int propertyIndex) {
return mutableContent == null ? null : mutableContent[propertyIndex];
}
/**
* Set the [json] content of a mutable property.
* Dirty detection set the next mutable property content and info .
* <p>
* Set here as the mutable property dirty detection is based on json content comparison.
* We only want to perform the json serialisation once so storing it here as part of
* dirty detection so that we can get it back to bind in insert or update etc.
*/
public void mutableContent(int propertyIndex, String content) {
if (mutableContent == null) {
mutableContent = new String[flags.length];
public void mutableNext(int propertyIndex, MutableValueNext next) {
if (mutableNext == null) {
mutableNext = new MutableValueNext[flags.length];
}
mutableContent[propertyIndex] = content;
mutableNext[propertyIndex] = next;
}
/**
* Update the 'next' mutable info returning the content that was obtained via dirty detection.
*/
public String mutableNext(int propertyIndex) {
if (mutableNext == null) {
return null;
}
final MutableValueNext next = mutableNext[propertyIndex];
mutableInfo(propertyIndex, next.info());
return next.content();
}
}
@@ -12,12 +12,15 @@ package io.ebean.bean;
public interface MutableValueInfo {
/**
* Compares the given json to an internal value. Can be a hash/checksum comparison
* or a plain JSON string comparison (based on {@code @DbJson(keepSource)}).
* Compares the given json returning null if deemed unchanged or returning
* the MutableValueNext to use if deemed dirty/changed.
* <p>
* Returning MutableValueNext allows an implementation based on hash/checksum
* to only perform that computation once.
*
* @return true if the value is considered unchanged (when comparing in json form).
* @return Null if deemed unchanged or the MutableValueNext if deemed changed.
*/
boolean isEqualToJson(String json);
MutableValueNext nextDirty(String json);
/**
* Compares the given object to an internal value.
@@ -0,0 +1,17 @@
package io.ebean.bean;
/**
* Represents a next value to use for mutable content properties (DbJson with jackson beans).
*/
public interface MutableValueNext {
/**
* Return the next content to use. Provided such that we serialise to json once.
*/
String content();
/**
* Return the next MutableValueInfo to use after an update.
*/
MutableValueInfo info();
}