#915 - Refactor internals - Change update plan to string key

This commit is contained in:
Rob Bygrave
2016-12-08 23:23:19 +13:00
parent 322a2f500d
commit ad0e085ff5
6 changed files with 34 additions and 38 deletions
@@ -696,40 +696,42 @@ public final class EntityBeanIntercept implements Serializable {
/**
* Return a dirty property hash taking into account embedded beans.
*/
public int getDirtyPropertyHash() {
return addDirtyPropertyHash(37);
public StringBuilder getDirtyPropertyKey() {
StringBuilder sb = new StringBuilder();
addDirtyPropertyKey(sb);
return sb;
}
/**
* Add and return a dirty property hash recursing into embedded beans.
*/
public int addDirtyPropertyHash(int hash) {
private void addDirtyPropertyKey(StringBuilder sb) {
int len = getPropertyLength();
for (int i = 0; i < len; i++) {
if (changedProps != null && changedProps[i]) {
// the property has been changed on this bean
hash = hash * 31 + (i + 1);
sb.append(i).append(',');
} else if (embeddedDirty != null && embeddedDirty[i]) {
// an embedded property has been changed - recurse
EntityBean embeddedBean = (EntityBean) owner._ebean_getField(i);
hash = hash * 31 + embeddedBean._ebean_getIntercept().addDirtyPropertyHash(hash);
sb.append(i).append('[');
embeddedBean._ebean_getIntercept().addDirtyPropertyKey(sb);
sb.append(']');
}
}
return hash;
}
/**
* Return a loaded property hash.
*/
public int getLoadedPropertyHash() {
int hash = 37;
public StringBuilder getLoadedPropertyKey() {
StringBuilder sb = new StringBuilder();
int len = getPropertyLength();
for (int i = 0; i < len; i++) {
if (isLoadedProperty(i)) {
hash = hash * 31 + (i + 1);
sb.append(i).append(',');
}
}
return hash;
return sb;
}
/**
@@ -41,12 +41,12 @@ public interface SpiUpdatePlan {
/**
* Return the time this plan was last used.
*/
Long getTimeLastUsed();
long getTimeLastUsed();
/**
* Return the hash key for this plan.
*/
Integer getKey();
String getKey();
/**
* Return the concurrency mode for this plan.
@@ -1020,27 +1020,27 @@ public final class PersistRequestBean<T> extends PersistRequest implements BeanP
/**
* Return the key for an update persist request.
*/
public int getUpdatePlanHash() {
public String getUpdatePlanHash() {
int hash;
StringBuilder key;
if (determineUpdateAllLoadedProperties()) {
hash = intercept.getLoadedPropertyHash();
key = intercept.getLoadedPropertyKey();
} else {
hash = intercept.getDirtyPropertyHash();
key = intercept.getDirtyPropertyKey();
}
BeanProperty versionProperty = beanDescriptor.getVersionProperty();
if (versionProperty != null) {
if (intercept.isLoadedProperty(versionProperty.getPropertyIndex())) {
hash = hash * 92821 + 7;
key.append('v');
}
}
if (publish) {
hash = hash * 92821;
key.append('p');
}
return hash;
return key.toString();
}
/**
@@ -101,7 +101,7 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
private static final Logger logger = LoggerFactory.getLogger(BeanDescriptor.class);
private final ConcurrentHashMap<Integer, SpiUpdatePlan> updatePlanCache = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, SpiUpdatePlan> updatePlanCache = new ConcurrentHashMap<>();
private final ConcurrentHashMap<CQueryPlanKey, CQueryPlan> queryPlanCache = new ConcurrentHashMap<>();
@@ -1447,14 +1447,14 @@ public class BeanDescriptor<T> implements MetaBeanInfo, BeanType<T> {
/**
* Get a UpdatePlan for a given hash.
*/
public SpiUpdatePlan getUpdatePlan(Integer key) {
public SpiUpdatePlan getUpdatePlan(String key) {
return updatePlanCache.get(key);
}
/**
* Add a UpdatePlan to the cache with a given hash.
*/
public void putUpdatePlan(Integer key, SpiUpdatePlan plan) {
public void putUpdatePlan(String key, SpiUpdatePlan plan) {
updatePlanCache.put(key, plan);
}
@@ -104,7 +104,7 @@ public final class UpdateMeta {
private SpiUpdatePlan getDynamicUpdatePlan(PersistRequestBean<?> persistRequest) {
int key = persistRequest.getUpdatePlanHash();
String key = persistRequest.getUpdatePlanHash();
// check if we can use a cached UpdatePlan
BeanDescriptor<?> beanDescriptor = persistRequest.getBeanDescriptor();
@@ -12,7 +12,7 @@ import java.sql.SQLException;
*/
public class UpdatePlan implements SpiUpdatePlan {
private final Integer key;
private final String key;
private final ConcurrencyMode mode;
@@ -24,21 +24,19 @@ public class UpdatePlan implements SpiUpdatePlan {
private final boolean emptySetClause;
private Long timeLastUsed;
private long timeLastUsed;
/**
* Create a non cached UpdatePlan.
*/
public UpdatePlan(ConcurrencyMode mode, String sql, Bindable set) {
UpdatePlan(ConcurrencyMode mode, String sql, Bindable set) {
this(null, mode, sql, set);
}
/**
* Create a UpdatePlan with a given key.
*/
public UpdatePlan(Integer key, ConcurrencyMode mode, String sql, Bindable set) {
UpdatePlan(String key, ConcurrencyMode mode, String sql, Bindable set) {
this.emptySetClause = (sql == null);
this.key = key;
this.mode = mode;
@@ -55,10 +53,8 @@ public class UpdatePlan implements SpiUpdatePlan {
* Run the prepared statement binding for the 'update set' properties.
*/
public void bindSet(DmlHandler bind, EntityBean bean) throws SQLException {
set.dmlBind(bind, bean);
// not strictly 'thread safe' but object assignment is atomic
// atomic on 64 bit jvm
this.timeLastUsed = System.currentTimeMillis();
}
@@ -72,16 +68,14 @@ public class UpdatePlan implements SpiUpdatePlan {
/**
* Return the time this plan was last used.
*/
public Long getTimeLastUsed() {
// not thread safe but atomic
public long getTimeLastUsed() {
return timeLastUsed;
}
/**
* Return the hash key.
* Return the key.
*/
public Integer getKey() {
public String getKey() {
return key;
}