diff --git a/src/main/java/net/helenus/core/AbstractSessionOperations.java b/src/main/java/net/helenus/core/AbstractSessionOperations.java index 0ab6fc3..c163f7f 100644 --- a/src/main/java/net/helenus/core/AbstractSessionOperations.java +++ b/src/main/java/net/helenus/core/AbstractSessionOperations.java @@ -18,15 +18,14 @@ package net.helenus.core; import java.io.PrintStream; import java.util.List; import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; -import com.google.common.base.Stopwatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.codahale.metrics.MetricRegistry; import com.datastax.driver.core.*; import com.datastax.driver.core.querybuilder.BuiltStatement; +import com.google.common.base.Stopwatch; import com.google.common.collect.Table; import com.google.common.util.concurrent.ListenableFuture; @@ -78,35 +77,35 @@ public abstract class AbstractSessionOperations { } } - public ResultSet execute(Statement statement, boolean showValues) { - return execute(statement, null, null, showValues); - } + public ResultSet execute(Statement statement, boolean showValues) { + return execute(statement, null, null, showValues); + } - public ResultSet execute(Statement statement, Stopwatch timer, boolean showValues) { - return execute(statement, null, timer, showValues); - } + public ResultSet execute(Statement statement, Stopwatch timer, boolean showValues) { + return execute(statement, null, timer, showValues); + } - public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { - return execute(statement, uow, null, showValues); - } + public ResultSet execute(Statement statement, UnitOfWork uow, boolean showValues) { + return execute(statement, uow, null, showValues); + } - public ResultSet execute(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + public ResultSet execute(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { return executeAsync(statement, uow, timer, showValues).getUninterruptibly(); } - public ResultSetFuture executeAsync(Statement statement, boolean showValues) { - return executeAsync(statement, null, null, showValues); - } + public ResultSetFuture executeAsync(Statement statement, boolean showValues) { + return executeAsync(statement, null, null, showValues); + } - public ResultSetFuture executeAsync(Statement statement, Stopwatch timer, boolean showValues) { - return executeAsync(statement, null, timer, showValues); - } + public ResultSetFuture executeAsync(Statement statement, Stopwatch timer, boolean showValues) { + return executeAsync(statement, null, timer, showValues); + } - public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { - return executeAsync(statement, uow, null, showValues); - } + public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, boolean showValues) { + return executeAsync(statement, uow, null, showValues); + } - public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { + public ResultSetFuture executeAsync(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { try { log(statement, uow, timer, showValues); return currentSession().executeAsync(statement); @@ -117,14 +116,14 @@ public abstract class AbstractSessionOperations { void log(Statement statement, UnitOfWork uow, Stopwatch timer, boolean showValues) { if (LOG.isInfoEnabled()) { - String timerString = ""; + String timerString = ""; String uowString = ""; if (uow != null) { uowString = (timer != null) ? " " : "" + "UOW(" + uow.hashCode() + ")"; } if (timer != null) { - timerString = String.format(" %s", timer.toString()); - } + timerString = String.format(" %s", timer.toString()); + } LOG.info(String.format("CQL%s%s - %s", uowString, timerString, statement)); } if (isShowCql()) { diff --git a/src/main/java/net/helenus/core/AbstractUnitOfWork.java b/src/main/java/net/helenus/core/AbstractUnitOfWork.java index a291390..73db315 100644 --- a/src/main/java/net/helenus/core/AbstractUnitOfWork.java +++ b/src/main/java/net/helenus/core/AbstractUnitOfWork.java @@ -60,19 +60,19 @@ public abstract class AbstractUnitOfWork implements UnitOfW } @Override - public void addDatabaseTime(String name, Stopwatch amount) { - Double time = databaseTime.get(name); - if (time == null) { - databaseTime.put(name, (double)amount.elapsed(TimeUnit.MICROSECONDS)); - } else { - databaseTime.put(name, time + amount.elapsed(TimeUnit.MICROSECONDS)); - } - } + public void addDatabaseTime(String name, Stopwatch amount) { + Double time = databaseTime.get(name); + if (time == null) { + databaseTime.put(name, (double) amount.elapsed(TimeUnit.MICROSECONDS)); + } else { + databaseTime.put(name, time + amount.elapsed(TimeUnit.MICROSECONDS)); + } + } - @Override - public void addCacheLookupTime(Stopwatch amount) { - cacheLookupTime += amount.elapsed(TimeUnit.MICROSECONDS); - } + @Override + public void addCacheLookupTime(Stopwatch amount) { + cacheLookupTime += amount.elapsed(TimeUnit.MICROSECONDS); + } @Override public void addNestedUnitOfWork(UnitOfWork uow) { diff --git a/src/main/java/net/helenus/core/HelenusSession.java b/src/main/java/net/helenus/core/HelenusSession.java index 19bf7d2..a80989f 100644 --- a/src/main/java/net/helenus/core/HelenusSession.java +++ b/src/main/java/net/helenus/core/HelenusSession.java @@ -207,11 +207,15 @@ public final class HelenusSession extends AbstractSessionOperations implements C UnboundFacet unboundFacet = (UnboundFacet) facet; UnboundFacet.Binder binder = unboundFacet.binder(); for (HelenusProperty prop : unboundFacet.getProperties()) { + Object value; if (valueMap == null) { - Object value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); - binder.setValueForProperty(prop, value.toString()); + value = BeanColumnValueProvider.INSTANCE.getColumnValue(pojo, -1, prop, false); + if (value != null) { + binder.setValueForProperty(prop, value.toString()); + } } else { - binder.setValueForProperty(prop, valueMap.get(prop.getPropertyName()).toString()); + value = valueMap.get(prop.getPropertyName()); + binder.setValueForProperty(prop, value.toString()); } } if (binder.isBound()) { diff --git a/src/main/java/net/helenus/core/UnitOfWork.java b/src/main/java/net/helenus/core/UnitOfWork.java index 6b4161e..e236509 100644 --- a/src/main/java/net/helenus/core/UnitOfWork.java +++ b/src/main/java/net/helenus/core/UnitOfWork.java @@ -25,8 +25,8 @@ import net.helenus.core.cache.Facet; public interface UnitOfWork extends AutoCloseable { /** - * Marks the beginning of a transactional section of work. Will write a recordCacheAndDatabaseOperationCount - * to the shared write-ahead log. + * Marks the beginning of a transactional section of work. Will write a + * recordCacheAndDatabaseOperationCount to the shared write-ahead log. * * @return the handle used to commit or abort the work. */ @@ -61,8 +61,8 @@ public interface UnitOfWork extends AutoCloseable { UnitOfWork setPurpose(String purpose); - void addDatabaseTime(String name, Stopwatch amount); - void addCacheLookupTime(Stopwatch amount); + void addDatabaseTime(String name, Stopwatch amount); + void addCacheLookupTime(Stopwatch amount); // Cache > 0 means "cache hit", < 0 means cache miss. void recordCacheAndDatabaseOperationCount(int cache, int database); diff --git a/src/main/java/net/helenus/core/operation/AbstractOperation.java b/src/main/java/net/helenus/core/operation/AbstractOperation.java index 4afbdc0..82e8fb2 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOperation.java @@ -31,10 +31,6 @@ public abstract class AbstractOperation> ex public abstract E transform(ResultSet resultSet); - public boolean cacheable() { - return false; - } - public PreparedOperation prepare() { return new PreparedOperation(prepareStatement(), this); } diff --git a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java index 6c23eb5..ca21e43 100644 --- a/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractOptionalOperation.java @@ -74,9 +74,9 @@ public abstract class AbstractOptionalOperation facets = bindFacetValues(); - cachedResult = checkCache(uow, facets); - if (cachedResult != null) { - result = Optional.of(cachedResult); - updateCache = false; - uowCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - uowCacheMiss.mark(); - if (isSessionCacheable()) { - String tableName = CacheUtil.schemaName(facets); - cachedResult = (E) sessionOps.checkCache(tableName, facets); - if (cachedResult != null) { - result = Optional.of(cachedResult); - sessionCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - sessionCacheMiss.mark(); - cacheMiss.mark(); - uow.recordCacheAndDatabaseOperationCount(-1, 0); - } - } - } - } finally { - timer.stop(); - uow.addCacheLookupTime(timer); - } + Stopwatch timer = Stopwatch.createStarted(); + try { + List facets = bindFacetValues(); + cachedResult = checkCache(uow, facets); + if (cachedResult != null) { + result = Optional.of(cachedResult); + updateCache = false; + uowCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + uowCacheMiss.mark(); + if (isSessionCacheable()) { + String tableName = CacheUtil.schemaName(facets); + cachedResult = (E) sessionOps.checkCache(tableName, facets); + if (cachedResult != null) { + result = Optional.of(cachedResult); + sessionCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + sessionCacheMiss.mark(); + cacheMiss.mark(); + uow.recordCacheAndDatabaseOperationCount(-1, 0); + } + } + } + } finally { + timer.stop(); + uow.addCacheLookupTime(timer); + } } if (!result.isPresent()) { diff --git a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java index 1b08a4c..ff84180 100644 --- a/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java +++ b/src/main/java/net/helenus/core/operation/AbstractStatementOperation.java @@ -338,11 +338,17 @@ public abstract class AbstractStatementOperation facets = bindFacetValues(); - cachedResult = checkCache(uow, facets); - if (cachedResult != null) { - resultStream = Stream.of(cachedResult); - updateCache = false; - uowCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - uowCacheMiss.mark(); - if (isSessionCacheable()) { - String tableName = CacheUtil.schemaName(facets); - cachedResult = (E) sessionOps.checkCache(tableName, facets); - if (cachedResult != null) { - resultStream = Stream.of(cachedResult); - sessionCacheHits.mark(); - cacheHits.mark(); - uow.recordCacheAndDatabaseOperationCount(1, 0); - } else { - sessionCacheMiss.mark(); - cacheMiss.mark(); - uow.recordCacheAndDatabaseOperationCount(-1, 0); - } - } - } - } finally { - timer.stop(); - uow.addCacheLookupTime(timer); - } + List facets = bindFacetValues(); + cachedResult = checkCache(uow, facets); + if (cachedResult != null) { + resultStream = Stream.of(cachedResult); + updateCache = false; + uowCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + uowCacheMiss.mark(); + if (isSessionCacheable()) { + String tableName = CacheUtil.schemaName(facets); + cachedResult = (E) sessionOps.checkCache(tableName, facets); + if (cachedResult != null) { + resultStream = Stream.of(cachedResult); + sessionCacheHits.mark(); + cacheHits.mark(); + uow.recordCacheAndDatabaseOperationCount(1, 0); + } else { + sessionCacheMiss.mark(); + cacheMiss.mark(); + uow.recordCacheAndDatabaseOperationCount(-1, 0); + } + } + } + } finally { + timer.stop(); + uow.addCacheLookupTime(timer); + } } if (resultStream == null) { diff --git a/src/main/java/net/helenus/core/operation/InsertOperation.java b/src/main/java/net/helenus/core/operation/InsertOperation.java index fe05cde..24243e5 100644 --- a/src/main/java/net/helenus/core/operation/InsertOperation.java +++ b/src/main/java/net/helenus/core/operation/InsertOperation.java @@ -27,6 +27,7 @@ import net.helenus.core.AbstractSessionOperations; import net.helenus.core.Getter; import net.helenus.core.Helenus; import net.helenus.core.UnitOfWork; +import net.helenus.core.cache.Facet; import net.helenus.core.reflect.DefaultPrimitiveTypes; import net.helenus.core.reflect.Drafted; import net.helenus.core.reflect.HelenusPropertyNode; @@ -246,4 +247,14 @@ public final class InsertOperation extends AbstractOperation getFacets() { + if (entity != null) { + return entity.getFacets(); + } else { + return new ArrayList(); + } + } + } diff --git a/src/main/java/net/helenus/core/operation/Operation.java b/src/main/java/net/helenus/core/operation/Operation.java index 89f673f..193dd82 100644 --- a/src/main/java/net/helenus/core/operation/Operation.java +++ b/src/main/java/net/helenus/core/operation/Operation.java @@ -15,6 +15,7 @@ */ package net.helenus.core.operation; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; @@ -36,23 +37,23 @@ import net.helenus.core.cache.Facet; public abstract class Operation { protected final AbstractSessionOperations sessionOps; - protected final Meter uowCacheHits; - protected final Meter uowCacheMiss; - protected final Meter sessionCacheHits; - protected final Meter sessionCacheMiss; - protected final Meter cacheHits; - protected final Meter cacheMiss; + protected final Meter uowCacheHits; + protected final Meter uowCacheMiss; + protected final Meter sessionCacheHits; + protected final Meter sessionCacheMiss; + protected final Meter cacheHits; + protected final Meter cacheMiss; protected final Timer requestLatency; Operation(AbstractSessionOperations sessionOperations) { this.sessionOps = sessionOperations; MetricRegistry metrics = sessionOperations.getMetricRegistry(); - this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); - this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); - this.sessionCacheHits = metrics.meter("net.helenus.session-cache-hits"); - this.sessionCacheMiss = metrics.meter("net.helenus.session-cache-miss"); - this.cacheHits = metrics.meter("net.helenus.cache-hits"); - this.cacheMiss = metrics.meter("net.helenus.cache-miss"); + this.uowCacheHits = metrics.meter("net.helenus.UOW-cache-hits"); + this.uowCacheMiss = metrics.meter("net.helenus.UOW-cache-miss"); + this.sessionCacheHits = metrics.meter("net.helenus.session-cache-hits"); + this.sessionCacheMiss = metrics.meter("net.helenus.session-cache-miss"); + this.cacheHits = metrics.meter("net.helenus.cache-hits"); + this.cacheMiss = metrics.meter("net.helenus.cache-miss"); this.requestLatency = metrics.timer("net.helenus.request-latency"); } @@ -77,17 +78,17 @@ public abstract class Operation { Statement statement = options(buildStatement(cached)); Stopwatch timer = Stopwatch.createStarted(); try { - ResultSetFuture futureResultSet = session.executeAsync(statement, uow, timer, showValues); - if (uow != null) - uow.recordCacheAndDatabaseOperationCount(0, 1); - ResultSet resultSet = futureResultSet.getUninterruptibly(); // TODO(gburd): (timeout, units); - return resultSet; + ResultSetFuture futureResultSet = session.executeAsync(statement, uow, timer, showValues); + if (uow != null) + uow.recordCacheAndDatabaseOperationCount(0, 1); + ResultSet resultSet = futureResultSet.getUninterruptibly(); // TODO(gburd): (timeout, units); + return resultSet; - } finally { - timer.stop(); - if (uow != null) - uow.addDatabaseTime("Cassandra", timer); - } + } finally { + timer.stop(); + if (uow != null) + uow.addDatabaseTime("Cassandra", timer); + } } finally { @@ -106,7 +107,7 @@ public abstract class Operation { } public List getFacets() { - return null; + return new ArrayList(); } public List bindFacetValues() { diff --git a/src/main/java/net/helenus/core/operation/UpdateOperation.java b/src/main/java/net/helenus/core/operation/UpdateOperation.java index 04ed538..4a7f2a3 100644 --- a/src/main/java/net/helenus/core/operation/UpdateOperation.java +++ b/src/main/java/net/helenus/core/operation/UpdateOperation.java @@ -25,6 +25,7 @@ import com.datastax.driver.core.querybuilder.QueryBuilder; import com.datastax.driver.core.querybuilder.Update; import net.helenus.core.*; +import net.helenus.core.cache.Facet; import net.helenus.core.reflect.HelenusPropertyNode; import net.helenus.mapping.HelenusEntity; import net.helenus.mapping.HelenusProperty; @@ -579,4 +580,14 @@ public final class UpdateOperation extends AbstractFilterOperation getFacets() { + if (entity != null) { + return entity.getFacets(); + } else { + return new ArrayList(); + } + } + } diff --git a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java index 7785da2..5872598 100644 --- a/src/main/java/net/helenus/mapping/HelenusMappingEntity.java +++ b/src/main/java/net/helenus/mapping/HelenusMappingEntity.java @@ -129,11 +129,11 @@ public final class HelenusMappingEntity implements HelenusEntity { primaryKeyProperties = null; } for (ConstraintValidator constraint : MappingUtil.getValidators(prop.getGetterMethod())) { - if (constraint.getClass().isAssignableFrom(DistinctValidator.class)) - ; - UnboundFacet facet = new UnboundFacet(prop); - facetsBuilder.add(facet); - break; + if (constraint.getClass().isAssignableFrom(DistinctValidator.class)) { + UnboundFacet facet = new UnboundFacet(prop); + facetsBuilder.add(facet); + break; + } } } }