Merge AutoTune refactor with master

This commit is contained in:
Robin Bygrave
2015-09-10 10:27:24 +12:00
82 changed files with 2538 additions and 2910 deletions
@@ -15,7 +15,6 @@ import com.avaje.ebean.meta.MetaInfoManager;
import com.avaje.ebean.plugin.SpiServer;
import com.avaje.ebean.text.csv.CsvReader;
import com.avaje.ebean.text.json.JsonContext;
import com.avaje.ebeaninternal.server.autofetch.AutoFetchManager;
import com.avaje.ebeaninternal.server.core.SpiOrmQueryRequest;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
import com.avaje.ebeaninternal.server.query.CQuery;
@@ -88,11 +87,6 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
return null;
}
@Override
public AutoFetchManager getAutoFetchManager() {
return null;
}
@Override
public ReadAuditLogger getReadAuditLogger() {
return null;
@@ -234,7 +228,7 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
}
@Override
public AdminAutofetch getAdminAutofetch() {
public AutoTune getAutoTune() {
return null;
}
@@ -0,0 +1,119 @@
package com.avaje.ebeaninternal.server.querydefn;
import com.avaje.ebean.BaseTestCase;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertNull;
public class OrmQueryDetailParserTest extends BaseTestCase {
@Test
public void testParseBasic() throws Exception {
OrmQueryDetail other = new OrmQueryDetail();
other.select("id,name");
OrmQueryProperties root = other.getChunk(null, false);
assertNull(root.getPath());
assertThat(root.getAllIncludedProperties()).contains("id", "name");
OrmQueryDetailParser p = new OrmQueryDetailParser("select (id,name)");
OrmQueryDetail detail = p.parse();
root = detail.getChunk(null, false);
assertNull(root.getPath());
assertThat(root.getAllIncludedProperties()).contains("id", "name");
}
@Test
public void testParseEmptySelect() throws Exception {
OrmQueryDetailParser p = new OrmQueryDetailParser("select fetch customer (email)");
OrmQueryDetail detail = p.parse();
OrmQueryProperties root = detail.getChunk(null, false);
assertNull(root.getPath());
assertThat(root.getAllIncludedProperties()).isNull();
OrmQueryProperties chunk = detail.getChunk("customer", false);
assertThat(chunk.getPath()).isEqualTo("customer");
assertThat(chunk.getAllIncludedProperties()).contains("email");
}
@Test
public void testParseSelectFetch() throws Exception {
OrmQueryDetailParser p = new OrmQueryDetailParser("select (id,name) fetch customer (email)");
OrmQueryDetail detail = p.parse();
OrmQueryProperties root = detail.getChunk(null, false);
assertNull(root.getPath());
assertThat(root.getAllIncludedProperties()).contains("id", "name");
OrmQueryProperties chunk = detail.getChunk("customer", false);
assertThat(chunk.getPath()).isEqualTo("customer");
assertThat(chunk.getAllIncludedProperties()).contains("email");
}
@Test
public void testParseSelectFetchMore() throws Exception {
OrmQueryDetailParser p = new OrmQueryDetailParser("select (id,name) fetch customer (email) fetch details.product (sku,description)");
OrmQueryDetail detail = p.parse();
OrmQueryProperties root = detail.getChunk(null, false);
assertNull(root.getPath());
assertThat(root.getAllIncludedProperties()).contains("id", "name");
OrmQueryProperties chunk = detail.getChunk("customer", false);
assertThat(chunk.getPath()).isEqualTo("customer");
assertThat(chunk.getAllIncludedProperties()).contains("email");
chunk = detail.getChunk("details.product", false);
assertThat(chunk.getPath()).isEqualTo("details.product");
assertThat(chunk.getAllIncludedProperties()).contains("sku","description");
}
@Test
public void testParseWithPlusQuery() throws Exception {
OrmQueryDetailParser p = new OrmQueryDetailParser("select (id,name) fetch customer (+query,id,name,email)");
OrmQueryDetail detail = p.parse();
OrmQueryProperties root = detail.getChunk(null, false);
assertNull(root.getPath());
assertThat(root.getAllIncludedProperties()).contains("id", "name");
OrmQueryProperties chunk = detail.getChunk("customer", false);
assertThat(chunk.getPath()).isEqualTo("customer");
assertThat(chunk.getAllIncludedProperties()).contains("id", "name", "email");
assertThat(chunk.isQueryFetch()).isTrue();
}
@Test
public void testTuneApply() {
OrmQueryDetailParser p = new OrmQueryDetailParser("select (status) fetch customer (email)");
OrmQueryDetail detail = p.parse();
OrmQueryDetailParser p2 = new OrmQueryDetailParser("select (id,name) fetch customer (+query,id,name,email)");
OrmQueryDetail tune = p2.parse();
detail.tuneFetchProperties(tune);
OrmQueryProperties root = detail.getChunk(null, false);
assertNull(root.getPath());
assertThat(root.getAllIncludedProperties()).contains("id", "name");
OrmQueryProperties chunk = detail.getChunk("customer", false);
assertThat(chunk.getPath()).isEqualTo("customer");
assertThat(chunk.getAllIncludedProperties()).contains("id", "name", "email");
assertThat(chunk.isQueryFetch()).isTrue();
}
}
@@ -0,0 +1,21 @@
package com.avaje.ebeaninternal.server.querydefn;
import org.junit.Test;
import static org.junit.Assert.*;
public class OrmQueryDetailTest {
@Test
public void test_isAutoTuneEqual() {
OrmQueryDetailParser parser1 = new OrmQueryDetailParser("select (id,name) fetch customer (name) fetch details (code)");
OrmQueryDetail detail1 = parser1.parse();
OrmQueryDetailParser parser2 = new OrmQueryDetailParser("select (id,name) fetch details (code) fetch customer (name)");
OrmQueryDetail detail2 = parser2.parse();
assertTrue(detail1.isAutoTuneEqual(detail2));
}
}
@@ -37,30 +37,30 @@ public class AutofetchEmbeddedTest extends BaseTestCase {
@Test
public void testEmbeddedBeanQueryTuning() {
Ebean.getServer(null).getAdminAutofetch().setProfiling(true);
Ebean.getServer(null).getAdminAutofetch().setQueryTuning(true);
Ebean.getServer(null).getAdminAutofetch().setProfilingBase(1);
EMain testBean = new EMain();
testBean.setName("test");
testBean.getEmbeddable().setDescription("test description");
Ebean.save(testBean);
//This should not throw an exception
for (int i = 0; i < 5; i++) {
Ebean.beginTransaction();
try {
List<EMain> result = Ebean.find(EMain.class).setAutofetch(true).findList();
for (EMain e : result) {
e.getEmbeddable().setDescription("Test" + i);
Ebean.save(e);
}
Ebean.commitTransaction();
} finally {
Ebean.endTransaction();
logger.debug(Ebean.getServer(null).getAdminAutofetch().collectUsageViaGC());
}
}
// Ebean.getServer(null).getAutoTune().setProfiling(true);
// Ebean.getServer(null).getAutoTune().setQueryTuning(true);
// Ebean.getServer(null).getAutoTune().setProfilingBase(1);
//
// EMain testBean = new EMain();
// testBean.setName("test");
// testBean.getEmbeddable().setDescription("test description");
// Ebean.save(testBean);
//
// //This should not throw an exception
// for (int i = 0; i < 5; i++) {
// Ebean.beginTransaction();
// try {
// List<EMain> result = Ebean.find(EMain.class).setAutofetch(true).findList();
// for (EMain e : result) {
// e.getEmbeddable().setDescription("Test" + i);
// Ebean.save(e);
// }
// Ebean.commitTransaction();
// } finally {
// Ebean.endTransaction();
// logger.debug(Ebean.getServer(null).getAutoTune().collectProfiling());
// }
// }
}
@Test
@@ -1,4 +1,4 @@
package com.avaje.ebeaninternal.server.autofetch;
package com.avaje.tests.autofetch;
import java.util.List;
import java.util.Set;
@@ -15,7 +15,7 @@ import com.avaje.ebean.bean.EntityBean;
import com.avaje.ebean.bean.EntityBeanIntercept;
import com.avaje.ebean.cache.ServerCacheManager;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.ebeaninternal.server.autofetch.TunedQueryInfo;
import com.avaje.ebeaninternal.server.autofetch.service.TunedQueryInfo;
import com.avaje.ebeaninternal.server.querydefn.OrmQueryDetail;
import com.avaje.tests.model.basic.Order;
import com.avaje.tests.model.basic.ResetBasicData;
@@ -41,11 +41,11 @@ public class TunedQueryInfoTest extends BaseTestCase {
OrmQueryDetail tunedDetail = new OrmQueryDetail();
tunedDetail.select(null);
TunedQueryInfo tunedInfo = new TunedQueryInfo(null, tunedDetail, 0);
TunedQueryInfo tunedInfo = new TunedQueryInfo(tunedDetail);
Query<Order> query = server.find(Order.class).setId(1);
tunedInfo.autoFetchTune((SpiQuery<?>)query);
tunedInfo.tuneQuery((SpiQuery<?>) query);
Order order = query.findUnique();
EntityBean eb = (EntityBean)order;
@@ -69,11 +69,11 @@ public class TunedQueryInfoTest extends BaseTestCase {
OrmQueryDetail tunedDetail = new OrmQueryDetail();
tunedDetail.select("");
TunedQueryInfo tunedInfo = new TunedQueryInfo(null, tunedDetail, 0);
TunedQueryInfo tunedInfo = new TunedQueryInfo(tunedDetail);
Query<Order> query = server.find(Order.class).setId(1);
tunedInfo.autoFetchTune((SpiQuery<?>)query);
tunedInfo.tuneQuery((SpiQuery<?>) query);
Order order = query.findUnique();
EntityBean eb = (EntityBean)order;
@@ -96,11 +96,11 @@ public class TunedQueryInfoTest extends BaseTestCase {
OrmQueryDetail tunedDetail = new OrmQueryDetail();
tunedDetail.select("somethingThatDoesNotExist");
TunedQueryInfo tunedInfo = new TunedQueryInfo(null, tunedDetail, 0);
TunedQueryInfo tunedInfo = new TunedQueryInfo(tunedDetail);
Query<Order> query = server.find(Order.class).setId(1);
tunedInfo.autoFetchTune((SpiQuery<?>)query);
tunedInfo.tuneQuery((SpiQuery<?>) query);
LoggedSqlCollector.start();
@@ -132,11 +132,11 @@ public class TunedQueryInfoTest extends BaseTestCase {
OrmQueryDetail tunedDetail = new OrmQueryDetail();
tunedDetail.select("status, customer");
TunedQueryInfo tunedInfo = new TunedQueryInfo(null, tunedDetail, 0);
TunedQueryInfo tunedInfo = new TunedQueryInfo(tunedDetail);
Query<Order> query = server.find(Order.class).setId(1);
tunedInfo.autoFetchTune((SpiQuery<?>)query);
tunedInfo.tuneQuery((SpiQuery<?>) query);
LoggedSqlCollector.start();
@@ -167,11 +167,11 @@ public class TunedQueryInfoTest extends BaseTestCase {
OrmQueryDetail tunedDetail = new OrmQueryDetail();
tunedDetail.select("status");
TunedQueryInfo tunedInfo = new TunedQueryInfo(null, tunedDetail, 0);
TunedQueryInfo tunedInfo = new TunedQueryInfo(tunedDetail);
Query<Order> query = server.find(Order.class).setId(1);
tunedInfo.autoFetchTune((SpiQuery<?>)query);
tunedInfo.tuneQuery((SpiQuery<?>) query);
LoggedSqlCollector.start();
@@ -1,4 +1,4 @@
package com.avaje.ebeaninternal.server.autofetch;
package com.avaje.tests.autofetch;
import java.util.List;
import java.util.Set;
@@ -1,44 +1,41 @@
package com.avaje.tests.basic;
import java.util.List;
import org.junit.Test;
import com.avaje.ebean.AdminAutofetch;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.Order;
import com.avaje.tests.model.basic.OrderDetail;
import com.avaje.tests.model.basic.ResetBasicData;
public class TestBatchLazy extends BaseTestCase {
@Test
public void testMe() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class);
List<Order> list = query.findList();
for (Order order : list) {
Customer customer = order.getCustomer();
customer.getName();
List<OrderDetail> details = order.getDetails();
for (OrderDetail orderDetail : details) {
orderDetail.getProduct().getSku();
}
}
AdminAutofetch adminAutofetch = Ebean.getServer(null).getAdminAutofetch();
adminAutofetch.collectUsageViaGC();
}
}
package com.avaje.tests.basic;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.Order;
import com.avaje.tests.model.basic.OrderDetail;
import com.avaje.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
public class TestBatchLazy extends BaseTestCase {
@Test
public void testMe() {
ResetBasicData.reset();
Query<Order> query = Ebean.find(Order.class);
List<Order> list = query.findList();
for (Order order : list) {
Customer customer = order.getCustomer();
customer.getName();
List<OrderDetail> details = order.getDetails();
for (OrderDetail orderDetail : details) {
orderDetail.getProduct().getSku();
}
}
Ebean.getDefaultServer().getAutoTune().collectProfiling();
}
}
@@ -24,8 +24,8 @@ public class TestByteOnly extends BaseTestCase {
Ebean.save(e2);
// Ebean.getServer(null).getAdminAutofetch().collectUsageViaGC();
// Ebean.getServer(null).getAdminAutofetch().updateTunedQueryInfo();
// Ebean.getServer(null).getAutoTune().collectProfiling();
// Ebean.getServer(null).getAutoTune().updateTunedQueryInfo();
System.out.println("done");
}
@@ -8,7 +8,7 @@ import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.ebean.cache.ServerCache;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.ebeaninternal.server.autofetch.TunedQueryInfo;
import com.avaje.ebeaninternal.server.autofetch.service.TunedQueryInfo;
import com.avaje.ebeaninternal.server.querydefn.OrmQueryDetail;
import com.avaje.tests.model.basic.FeatureDescription;
@@ -28,11 +28,11 @@ public class TestL2CacheWithSharedBean extends BaseTestCase {
OrmQueryDetail tunedDetail = new OrmQueryDetail();
tunedDetail.select("name");
TunedQueryInfo tunedInfo = new TunedQueryInfo(null, tunedDetail, 0);
TunedQueryInfo tunedInfo = new TunedQueryInfo(tunedDetail);
Query<FeatureDescription> query = Ebean.find(FeatureDescription.class).setId(f1.getId());
tunedInfo.autoFetchTune((SpiQuery<?>) query);
tunedInfo.tuneQuery((SpiQuery<?>) query);
query.findUnique(); // PUT into cache
@@ -1,79 +1,78 @@
package com.avaje.tests.query;
import java.util.List;
import org.junit.Test;
import com.avaje.ebean.AdminAutofetch;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.ebean.bean.ObjectGraphNode;
import com.avaje.ebean.bean.ObjectGraphOrigin;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.tests.model.basic.Address;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.Order;
import com.avaje.tests.model.basic.ResetBasicData;
public class TestAutofetchTuneWithJoin extends BaseTestCase {
@Test
public void test() {
runQuery();
collectUsage();
}
private void runQuery() {
ResetBasicData.reset();
Query<Order> q = Ebean.find(Order.class).setAutofetch(true).fetch("customer")
.fetch("customer.contacts").where().lt("id", 3).query();
List<Order> list = q.findList();
for (int i = 0; i < list.size(); i++) {
Order order = list.get(i);
order.getOrderDate();
order.getShipDate();
// order.setShipDate(new Date(System.currentTimeMillis()));
Customer customer = order.getCustomer();
customer.getName();
Address shippingAddress = customer.getShippingAddress();
if (shippingAddress != null) {
shippingAddress.getLine1();
shippingAddress.getCity();
}
// customer.getContacts()
}
SpiQuery<?> sq = (SpiQuery<?>) q;
ObjectGraphNode parentNode = sq.getParentNode();
ObjectGraphOrigin origin = parentNode.getOriginQueryPoint();
System.out.println("Origin:" + origin.getKey());
// MetaAutoFetchStatistic metaAutoFetchStatistic =
// ((DefaultOrmQuery<?>)q).getMetaAutoFetchStatistic();
// if (metaAutoFetchStatistic != null) {
// List<NodeUsageStats> nodeUsageStats =
// metaAutoFetchStatistic.getNodeUsageStats();
// System.out.println(nodeUsageStats);
// List<QueryStats> queryStats = metaAutoFetchStatistic.getQueryStats();
// System.out.println(queryStats);
// }
if (q.isAutofetchTuned()) {
System.out.println("TUNED...");
}
}
private static void collectUsage() {
AdminAutofetch adminAutofetch = Ebean.getServer(null).getAdminAutofetch();
adminAutofetch.collectUsageViaGC();
}
}
package com.avaje.tests.query;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Query;
import com.avaje.ebean.bean.ObjectGraphNode;
import com.avaje.ebean.bean.ObjectGraphOrigin;
import com.avaje.ebeaninternal.api.SpiQuery;
import com.avaje.tests.model.basic.Address;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.Order;
import com.avaje.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
public class TestAutofetchTuneWithJoin extends BaseTestCase {
@Test
public void test() {
runQuery();
collectUsage();
}
private void runQuery() {
ResetBasicData.reset();
Query<Order> q = Ebean.find(Order.class)
.setAutofetch(true)
//.fetch("customer")
//.fetch("customer.contacts")
.where().lt("id", 3).query();
List<Order> list = q.findList();
for (int i = 0; i < list.size(); i++) {
Order order = list.get(i);
order.getOrderDate();
order.getShipDate();
// order.setShipDate(new Date(System.currentTimeMillis()));
Customer customer = order.getCustomer();
customer.getName();
Address shippingAddress = customer.getShippingAddress();
if (shippingAddress != null) {
shippingAddress.getLine1();
shippingAddress.getCity();
}
// customer.getContacts()
}
SpiQuery<?> sq = (SpiQuery<?>) q;
ObjectGraphNode parentNode = sq.getParentNode();
ObjectGraphOrigin origin = parentNode.getOriginQueryPoint();
System.out.println("Origin:" + origin.getKey());
// MetaAutoFetchStatistic metaAutoFetchStatistic =
// ((DefaultOrmQuery<?>)q).getMetaAutoFetchStatistic();
// if (metaAutoFetchStatistic != null) {
// List<NodeUsageStats> nodeUsageStats =
// metaAutoFetchStatistic.getNodeUsageStats();
// System.out.println(nodeUsageStats);
// List<QueryStats> queryStats = metaAutoFetchStatistic.getQueryStats();
// System.out.println(queryStats);
// }
if (q.isAutofetchTuned()) {
System.out.println("TUNED...");
}
}
private static void collectUsage() {
Ebean.getDefaultServer().getAutoTune().collectProfiling();
}
}
@@ -0,0 +1,96 @@
package com.avaje.tests.query.autotune;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;
import com.avaje.tests.model.basic.Address;
import com.avaje.tests.model.basic.Customer;
import com.avaje.tests.model.basic.Order;
import com.avaje.tests.model.basic.OrderDetail;
import com.avaje.tests.model.basic.ResetBasicData;
import org.junit.Test;
import java.util.List;
public class TestAutoTuneProfiling extends BaseTestCase {
@Test
public void test() {
ResetBasicData.reset();
for (int i = 0; i < 1; i++) {
execute();
}
collectUsage();
}
private void execute() {
useOrderDate();
useOrderDateCustomerName();
useLots();
useLotUntuned();
}
private Order findById(long id) {
return Ebean.find(Order.class)
.select("status, orderDate, shipDate")
.setId(id)
.findUnique();
}
private void useOrderDate() {
Order order = findById(3);
order.getStatus();
order.getShipDate();
}
private void useOrderDateCustomerName() {
Order order = findById(3);
order.getOrderDate();
order.getCustomer().getName();
}
private void useLots() {
Order order = findById(3);
order.getOrderDate();
order.getShipDate();
// order.setShipDate(new Date(System.currentTimeMillis()));
Customer customer = order.getCustomer();
customer.getName();
Address shippingAddress = customer.getShippingAddress();
if (shippingAddress != null) {
shippingAddress.getLine1();
shippingAddress.getCity();
}
}
private void useLotUntuned() {
Order order = findById(3);
List<OrderDetail> details = order.getDetails();
for (OrderDetail detail : details) {
detail.getProduct().getName();
detail.getOrderQty();
detail.getShipQty();
detail.getUnitPrice();
}
Customer customer = order.getCustomer();
customer.getName();
Address billingAddress = customer.getBillingAddress();
if (billingAddress != null) {
billingAddress.getCity();
billingAddress.getLine1();
billingAddress.getLine2();
}
}
private static void collectUsage() {
Ebean.getDefaultServer().getAutoTune().collectProfiling();
}
}
@@ -1,4 +1,4 @@
package com.avaje.ebeaninternal.server.transaction;
package com.avaje.tests.transaction;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.EbeanServer;
@@ -1,4 +1,4 @@
package com.avaje.ebeaninternal.server.transaction;
package com.avaje.tests.transaction;
import com.avaje.ebean.BaseTestCase;
import com.avaje.ebean.Ebean;