diff --git a/demo/pom.xml b/demo/pom.xml
index a38ea52..8fb95a3 100644
--- a/demo/pom.xml
+++ b/demo/pom.xml
@@ -25,6 +25,11 @@
contiguous-jdbc
1.0-SNAPSHOT
+
+ nl.sanderhautvast
+ contiguous-jackson
+ 1.0-SNAPSHOT
+
org.springframework.boot
spring-boot-starter-web
diff --git a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/DemoApplication.java b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/DemoApplication.java
index 24d495c..6919b2f 100644
--- a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/DemoApplication.java
+++ b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/DemoApplication.java
@@ -1,6 +1,9 @@
package nl.sanderhautvast.contiguous.demo;
+import com.fasterxml.jackson.databind.Module;
+import com.fasterxml.jackson.databind.module.SimpleModule;
import lombok.extern.slf4j.Slf4j;
+import nl.sanderhautvast.contiguous.ListSerializer;
import nl.sanderhautvast.contiguous.demo.repository.RandomStuffGenerator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
@@ -40,7 +43,7 @@ public class DemoApplication {
jdbcTemplate.execute("drop table if exists customers");
jdbcTemplate.execute("create table customers (name varchar(100), email varchar(100), streetname varchar(100), housenumber integer, city varchar(100), country varchar(100))");
final RandomStuffGenerator generator = new RandomStuffGenerator();
- for (int i = 0; i < 100_000; i++) {
+ for (int i = 0; i < 10_000; i++) {
jdbcTemplate.update("insert into customers (name, email, streetname, housenumber, city, country) values(?,?,?,?,?,?)",
ps -> {
String firstName = generator.generateFirstName();
@@ -57,6 +60,14 @@ public class DemoApplication {
};
}
+ @Bean
+ public Module jacksonModule() {
+ final SimpleModule module = new SimpleModule("contiguous_module");
+ module.addSerializer(new ListSerializer());
+ return module;
+ }
+
+
@Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(datasource());
diff --git a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/model/Customer.java b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/model/Customer.java
index 7c8bde2..a67c23c 100644
--- a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/model/Customer.java
+++ b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/model/Customer.java
@@ -1,10 +1,14 @@
package nl.sanderhautvast.contiguous.demo.model;
+import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
+import lombok.NoArgsConstructor;
@Data
@Builder
+@NoArgsConstructor
+@AllArgsConstructor
public class Customer {
String name;
String email;
diff --git a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/repository/CustomerRepository.java b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/repository/CustomerRepository.java
index 7354995..b5bfbda 100644
--- a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/repository/CustomerRepository.java
+++ b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/repository/CustomerRepository.java
@@ -9,6 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
+import java.util.List;
+
@Repository
@Slf4j
public class CustomerRepository {
@@ -21,7 +23,21 @@ public class CustomerRepository {
}
public ContiguousList getAllCustomers() {
- return jdbcTemplate.query("select * from customers limit 5", rs -> {
+ return jdbcTemplate.query("select * from customers limit 10000", rs -> {
+ return JdbcResults.toList(rs, Customer.class);
+ });
+ }
+
+ public List getAllCustomersTraditional() {
+ return jdbcTemplate.query("select * from customers", (rs, rowNum) -> new Customer(
+ rs.getString("name"),rs.getString("email"),
+ rs.getString("streetname"), rs.getInt("housenumber"),
+ rs.getString("city"), rs.getString("country")
+ ));
+ }
+
+ public List getAllCustomersHybrid() {
+ return jdbcTemplate.query("select * from customers", rs -> {
return JdbcResults.toList(rs, Customer.class);
});
}
diff --git a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/rest/DemoRestApi.java b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/rest/DemoRestApi.java
index f4fa1e2..c6d83ef 100644
--- a/demo/src/main/java/nl/sanderhautvast/contiguous/demo/rest/DemoRestApi.java
+++ b/demo/src/main/java/nl/sanderhautvast/contiguous/demo/rest/DemoRestApi.java
@@ -22,14 +22,17 @@ public class DemoRestApi {
}
@GetMapping(value = "/api/customers", produces = "application/json")
- public List getCustomers() {
- try {
- ContiguousList customers = customerRepository.getAllCustomers();
- log.info("customers {}", customers.size());
- return customers;
- } catch (Exception e) {
- log.error("Error", e);
- throw new RuntimeException(e);
- }
+ public ContiguousList getCustomers() {
+ return customerRepository.getAllCustomers();
+ }
+
+ @GetMapping(value = "/api/customers/traditional", produces = "application/json")
+ public List getCustomersTraditional() {
+ return customerRepository.getAllCustomersTraditional();
+ }
+
+ @GetMapping(value = "/api/customers/hybrid", produces = "application/json")
+ public List getCustomersHybrid() {
+ return customerRepository.getAllCustomersHybrid();
}
}
diff --git a/demo/src/main/resources/application.properties b/demo/src/main/resources/application.properties
index 03a223e..0b382d9 100644
--- a/demo/src/main/resources/application.properties
+++ b/demo/src/main/resources/application.properties
@@ -1,4 +1,3 @@
-logging.level.org.springframework=ERROR
spring.jpa.hibernate.ddl-auto=none
spring.datasource.driverClass=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
diff --git a/jmeter-test.jmx b/jmeter-test.jmx
new file mode 100644
index 0000000..b799a2d
--- /dev/null
+++ b/jmeter-test.jmx
@@ -0,0 +1,163 @@
+
+
+
+
+
+ false
+ true
+ false
+
+
+
+
+
+
+
+ continue
+
+ false
+ 100
+
+ 1
+ 1
+ false
+
+
+ true
+
+
+
+
+
+
+ localhost
+ 8080
+ http
+
+ /api/customers
+ GET
+ true
+ false
+ true
+ false
+
+
+
+
+
+
+
+
+
+ localhost
+ 8080
+ http
+
+ api/customers/traditional
+ GET
+ true
+ false
+ true
+ false
+
+
+
+
+
+
+
+
+
+ localhost
+ 8080
+ http
+
+ api/customers/hybrid
+ GET
+ true
+ false
+ true
+ false
+
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+
+ true
+ true
+ true
+
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+ false
+
+ saveConfig
+
+
+ true
+ true
+ true
+
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ true
+ false
+ false
+ false
+ true
+ 0
+ true
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+
+
diff --git a/lib/src/main/java/nl/sanderhautvast/contiguous/ContiguousList.java b/lib/src/main/java/nl/sanderhautvast/contiguous/ContiguousList.java
index 763bc69..25fce45 100644
--- a/lib/src/main/java/nl/sanderhautvast/contiguous/ContiguousList.java
+++ b/lib/src/main/java/nl/sanderhautvast/contiguous/ContiguousList.java
@@ -56,11 +56,11 @@ public class ContiguousList extends NotImplementedList implements List
/*
* storage for dehydated objects
*/
- private ByteBuffer data = ByteBuffer.allocate(32);
+ private ByteBuffer data = ByteBuffer.allocate(4096);//TODO create constructor with capacity
private int bufferPosition;
- private int[] elementIndices = new int[10]; // avoids autoboxing. Could also use standard ArrayList though
+ private ArrayList elementIndices = new ArrayList<>(); // avoids autoboxing. Could also use standard ArrayList though
// is there a standard lib IntList??
private int size;
@@ -69,11 +69,7 @@ public class ContiguousList extends NotImplementedList implements List
public ContiguousList(Class type) {
inspectType(type);
- elementIndices[0] = 0; // index of first element
- }
-
- public Class> getElementType() {
- return rootHandler.getType();
+ elementIndices.add(0); // index of first element
}
/*
@@ -136,13 +132,7 @@ public class ContiguousList extends NotImplementedList implements List
return false;
}
storePropertyData(element, rootHandler);
- size += 1;
-
- // keep track of where the objects are stored
- if (elementIndices.length < size + 1) {
- this.elementIndices = Arrays.copyOf(this.elementIndices, this.elementIndices.length * 2);
- }
- elementIndices[size] = bufferPosition;
+ extend();
return true;
}
@@ -189,7 +179,7 @@ public class ContiguousList extends NotImplementedList implements List
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("index <0 or >" + size);
}
- data.position(elementIndices[index]);
+ data.position(elementIndices.get(index));
try {
if (rootHandler instanceof BuiltinTypeHandler>) {
Object read = ValueReader.read(data);
@@ -278,14 +268,14 @@ public class ContiguousList extends NotImplementedList implements List
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("index <0 or >" + size);
}
- data.position(elementIndices[index]);
+ data.position(elementIndices.get(index));
if (rootHandler instanceof BuiltinTypeHandler>) {
BuiltinTypeHandler> handler = (BuiltinTypeHandler>) rootHandler;
return getValue(handler);
}
// create a new instance of the list element type
- StringBuilder s = new StringBuilder();
+ StringBuilder s = new StringBuilder(300);
s.append("{");
copyDataIntoStringBuilder(s, (CompoundTypeHandler) rootHandler);
s.append("}");
@@ -303,7 +293,7 @@ public class ContiguousList extends NotImplementedList implements List
}
private static String quote(String out) {
- StringBuilder s = new StringBuilder();
+ StringBuilder s = new StringBuilder(out.length() + 2);
out = s.append("\"").append(out).append("\"").toString();
return out;
}
@@ -315,9 +305,9 @@ public class ContiguousList extends NotImplementedList implements List
compoundType.getProperties().forEach(property -> {
if (property instanceof BuiltinTypeHandler) {
BuiltinTypeHandler> typeHandler = (BuiltinTypeHandler>) property;
- String name = typeHandler.getName();
- String value = getValue(typeHandler);
- s.append(quote(name)).append(": ").append(value);
+ s.append(quote(typeHandler.getName()))
+ .append(": ")
+ .append(getValue(typeHandler));
} else {
CompoundTypeHandler p = (CompoundTypeHandler) property;
s.append(p.getName()).append(":{");
@@ -608,16 +598,14 @@ public class ContiguousList extends NotImplementedList implements List
// used by SetterIterator
void extend() {
size += 1;
+ // keep track of index of element in data
+ elementIndices.add(bufferPosition);
}
byte[] getData() {
return Arrays.copyOfRange(data.array(), 0, bufferPosition);
}
- int[] getElementIndices() {
- return Arrays.copyOfRange(elementIndices, 0, size + 1);
- }
-
private void ensureFree(int length) {
while (bufferPosition + length > data.capacity()) {
byte[] bytes = this.data.array();