ready for performance test
This commit is contained in:
parent
dd6b9c2281
commit
f61a1e672d
8 changed files with 226 additions and 37 deletions
|
|
@ -25,6 +25,11 @@
|
||||||
<artifactId>contiguous-jdbc</artifactId>
|
<artifactId>contiguous-jdbc</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>nl.sanderhautvast</groupId>
|
||||||
|
<artifactId>contiguous-jackson</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
package nl.sanderhautvast.contiguous.demo;
|
package nl.sanderhautvast.contiguous.demo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.Module;
|
||||||
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import nl.sanderhautvast.contiguous.ListSerializer;
|
||||||
import nl.sanderhautvast.contiguous.demo.repository.RandomStuffGenerator;
|
import nl.sanderhautvast.contiguous.demo.repository.RandomStuffGenerator;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.CommandLineRunner;
|
import org.springframework.boot.CommandLineRunner;
|
||||||
|
|
@ -40,7 +43,7 @@ public class DemoApplication {
|
||||||
jdbcTemplate.execute("drop table if exists customers");
|
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))");
|
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();
|
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(?,?,?,?,?,?)",
|
jdbcTemplate.update("insert into customers (name, email, streetname, housenumber, city, country) values(?,?,?,?,?,?)",
|
||||||
ps -> {
|
ps -> {
|
||||||
String firstName = generator.generateFirstName();
|
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
|
@Bean
|
||||||
public JdbcTemplate jdbcTemplate() {
|
public JdbcTemplate jdbcTemplate() {
|
||||||
return new JdbcTemplate(datasource());
|
return new JdbcTemplate(datasource());
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
package nl.sanderhautvast.contiguous.demo.model;
|
package nl.sanderhautvast.contiguous.demo.model;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
public class Customer {
|
public class Customer {
|
||||||
String name;
|
String name;
|
||||||
String email;
|
String email;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class CustomerRepository {
|
public class CustomerRepository {
|
||||||
|
|
@ -21,7 +23,21 @@ public class CustomerRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContiguousList<Customer> getAllCustomers() {
|
public ContiguousList<Customer> 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<Customer> 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<Customer> getAllCustomersHybrid() {
|
||||||
|
return jdbcTemplate.query("select * from customers", rs -> {
|
||||||
return JdbcResults.toList(rs, Customer.class);
|
return JdbcResults.toList(rs, Customer.class);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,14 +22,17 @@ public class DemoRestApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(value = "/api/customers", produces = "application/json")
|
@GetMapping(value = "/api/customers", produces = "application/json")
|
||||||
public List<Customer> getCustomers() {
|
public ContiguousList<Customer> getCustomers() {
|
||||||
try {
|
return customerRepository.getAllCustomers();
|
||||||
ContiguousList<Customer> customers = customerRepository.getAllCustomers();
|
}
|
||||||
log.info("customers {}", customers.size());
|
|
||||||
return customers;
|
@GetMapping(value = "/api/customers/traditional", produces = "application/json")
|
||||||
} catch (Exception e) {
|
public List<Customer> getCustomersTraditional() {
|
||||||
log.error("Error", e);
|
return customerRepository.getAllCustomersTraditional();
|
||||||
throw new RuntimeException(e);
|
}
|
||||||
}
|
|
||||||
|
@GetMapping(value = "/api/customers/hybrid", produces = "application/json")
|
||||||
|
public List<Customer> getCustomersHybrid() {
|
||||||
|
return customerRepository.getAllCustomersHybrid();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
logging.level.org.springframework=ERROR
|
|
||||||
spring.jpa.hibernate.ddl-auto=none
|
spring.jpa.hibernate.ddl-auto=none
|
||||||
spring.datasource.driverClass=org.postgresql.Driver
|
spring.datasource.driverClass=org.postgresql.Driver
|
||||||
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
|
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
|
||||||
|
|
|
||||||
163
jmeter-test.jmx
Normal file
163
jmeter-test.jmx
Normal file
|
|
@ -0,0 +1,163 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.5">
|
||||||
|
<hashTree>
|
||||||
|
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
|
||||||
|
<stringProp name="TestPlan.comments"></stringProp>
|
||||||
|
<boolProp name="TestPlan.functional_mode">false</boolProp>
|
||||||
|
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
|
||||||
|
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
|
||||||
|
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||||
|
<collectionProp name="Arguments.arguments"/>
|
||||||
|
</elementProp>
|
||||||
|
<stringProp name="TestPlan.user_define_classpath"></stringProp>
|
||||||
|
</TestPlan>
|
||||||
|
<hashTree>
|
||||||
|
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
|
||||||
|
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
|
||||||
|
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
|
||||||
|
<boolProp name="LoopController.continue_forever">false</boolProp>
|
||||||
|
<stringProp name="LoopController.loops">100</stringProp>
|
||||||
|
</elementProp>
|
||||||
|
<stringProp name="ThreadGroup.num_threads">1</stringProp>
|
||||||
|
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
|
||||||
|
<boolProp name="ThreadGroup.scheduler">false</boolProp>
|
||||||
|
<stringProp name="ThreadGroup.duration"></stringProp>
|
||||||
|
<stringProp name="ThreadGroup.delay"></stringProp>
|
||||||
|
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
|
||||||
|
</ThreadGroup>
|
||||||
|
<hashTree>
|
||||||
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="contiguous" enabled="false">
|
||||||
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||||
|
<collectionProp name="Arguments.arguments"/>
|
||||||
|
</elementProp>
|
||||||
|
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port">8080</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">/api/customers</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||||
|
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree/>
|
||||||
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="traditional" enabled="true">
|
||||||
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||||
|
<collectionProp name="Arguments.arguments"/>
|
||||||
|
</elementProp>
|
||||||
|
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port">8080</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">api/customers/traditional</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||||
|
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree/>
|
||||||
|
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="hybrid" enabled="false">
|
||||||
|
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
|
||||||
|
<collectionProp name="Arguments.arguments"/>
|
||||||
|
</elementProp>
|
||||||
|
<stringProp name="HTTPSampler.domain">localhost</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.port">8080</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.protocol">http</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.path">api/customers/hybrid</stringProp>
|
||||||
|
<stringProp name="HTTPSampler.method">GET</stringProp>
|
||||||
|
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
|
||||||
|
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
|
||||||
|
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
|
||||||
|
<stringProp name="HTTPSampler.response_timeout"></stringProp>
|
||||||
|
</HTTPSamplerProxy>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
<ResultCollector guiclass="StatVisualizer" testclass="ResultCollector" testname="Aggregate Report" enabled="true">
|
||||||
|
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||||
|
<objProp>
|
||||||
|
<name>saveConfig</name>
|
||||||
|
<value class="SampleSaveConfiguration">
|
||||||
|
<time>true</time>
|
||||||
|
<latency>true</latency>
|
||||||
|
<timestamp>true</timestamp>
|
||||||
|
<success>true</success>
|
||||||
|
<label>true</label>
|
||||||
|
<code>true</code>
|
||||||
|
<message>true</message>
|
||||||
|
<threadName>true</threadName>
|
||||||
|
<dataType>true</dataType>
|
||||||
|
<encoding>false</encoding>
|
||||||
|
<assertions>true</assertions>
|
||||||
|
<subresults>true</subresults>
|
||||||
|
<responseData>false</responseData>
|
||||||
|
<samplerData>false</samplerData>
|
||||||
|
<xml>false</xml>
|
||||||
|
<fieldNames>true</fieldNames>
|
||||||
|
<responseHeaders>false</responseHeaders>
|
||||||
|
<requestHeaders>false</requestHeaders>
|
||||||
|
<responseDataOnError>false</responseDataOnError>
|
||||||
|
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||||
|
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||||
|
<bytes>true</bytes>
|
||||||
|
<sentBytes>true</sentBytes>
|
||||||
|
<url>true</url>
|
||||||
|
<threadCounts>true</threadCounts>
|
||||||
|
<idleTime>true</idleTime>
|
||||||
|
<connectTime>true</connectTime>
|
||||||
|
</value>
|
||||||
|
</objProp>
|
||||||
|
<stringProp name="filename"></stringProp>
|
||||||
|
</ResultCollector>
|
||||||
|
<hashTree/>
|
||||||
|
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="false">
|
||||||
|
<boolProp name="ResultCollector.error_logging">false</boolProp>
|
||||||
|
<objProp>
|
||||||
|
<name>saveConfig</name>
|
||||||
|
<value class="SampleSaveConfiguration">
|
||||||
|
<time>true</time>
|
||||||
|
<latency>true</latency>
|
||||||
|
<timestamp>true</timestamp>
|
||||||
|
<success>true</success>
|
||||||
|
<label>true</label>
|
||||||
|
<code>true</code>
|
||||||
|
<message>true</message>
|
||||||
|
<threadName>true</threadName>
|
||||||
|
<dataType>true</dataType>
|
||||||
|
<encoding>false</encoding>
|
||||||
|
<assertions>true</assertions>
|
||||||
|
<subresults>true</subresults>
|
||||||
|
<responseData>false</responseData>
|
||||||
|
<samplerData>false</samplerData>
|
||||||
|
<xml>false</xml>
|
||||||
|
<fieldNames>true</fieldNames>
|
||||||
|
<responseHeaders>false</responseHeaders>
|
||||||
|
<requestHeaders>false</requestHeaders>
|
||||||
|
<responseDataOnError>false</responseDataOnError>
|
||||||
|
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
|
||||||
|
<assertionsResultsToSave>0</assertionsResultsToSave>
|
||||||
|
<bytes>true</bytes>
|
||||||
|
<sentBytes>true</sentBytes>
|
||||||
|
<url>true</url>
|
||||||
|
<threadCounts>true</threadCounts>
|
||||||
|
<idleTime>true</idleTime>
|
||||||
|
<connectTime>true</connectTime>
|
||||||
|
</value>
|
||||||
|
</objProp>
|
||||||
|
<stringProp name="filename"></stringProp>
|
||||||
|
</ResultCollector>
|
||||||
|
<hashTree/>
|
||||||
|
</hashTree>
|
||||||
|
</hashTree>
|
||||||
|
</jmeterTestPlan>
|
||||||
|
|
@ -56,11 +56,11 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
||||||
/*
|
/*
|
||||||
* storage for dehydated objects
|
* 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 bufferPosition;
|
||||||
|
|
||||||
private int[] elementIndices = new int[10]; // avoids autoboxing. Could also use standard ArrayList though
|
private ArrayList<Integer> elementIndices = new ArrayList<>(); // avoids autoboxing. Could also use standard ArrayList though
|
||||||
// is there a standard lib IntList??
|
// is there a standard lib IntList??
|
||||||
|
|
||||||
private int size;
|
private int size;
|
||||||
|
|
@ -69,11 +69,7 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
||||||
|
|
||||||
public ContiguousList(Class<E> type) {
|
public ContiguousList(Class<E> type) {
|
||||||
inspectType(type);
|
inspectType(type);
|
||||||
elementIndices[0] = 0; // index of first element
|
elementIndices.add(0); // index of first element
|
||||||
}
|
|
||||||
|
|
||||||
public Class<?> getElementType() {
|
|
||||||
return rootHandler.getType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -136,13 +132,7 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
storePropertyData(element, rootHandler);
|
storePropertyData(element, rootHandler);
|
||||||
size += 1;
|
extend();
|
||||||
|
|
||||||
// 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;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,7 +179,7 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
||||||
if (index < 0 || index >= size) {
|
if (index < 0 || index >= size) {
|
||||||
throw new IndexOutOfBoundsException("index <0 or >" + size);
|
throw new IndexOutOfBoundsException("index <0 or >" + size);
|
||||||
}
|
}
|
||||||
data.position(elementIndices[index]);
|
data.position(elementIndices.get(index));
|
||||||
try {
|
try {
|
||||||
if (rootHandler instanceof BuiltinTypeHandler<?>) {
|
if (rootHandler instanceof BuiltinTypeHandler<?>) {
|
||||||
Object read = ValueReader.read(data);
|
Object read = ValueReader.read(data);
|
||||||
|
|
@ -278,14 +268,14 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
||||||
if (index < 0 || index >= size) {
|
if (index < 0 || index >= size) {
|
||||||
throw new IndexOutOfBoundsException("index <0 or >" + size);
|
throw new IndexOutOfBoundsException("index <0 or >" + size);
|
||||||
}
|
}
|
||||||
data.position(elementIndices[index]);
|
data.position(elementIndices.get(index));
|
||||||
if (rootHandler instanceof BuiltinTypeHandler<?>) {
|
if (rootHandler instanceof BuiltinTypeHandler<?>) {
|
||||||
|
|
||||||
BuiltinTypeHandler<?> handler = (BuiltinTypeHandler<?>) rootHandler;
|
BuiltinTypeHandler<?> handler = (BuiltinTypeHandler<?>) rootHandler;
|
||||||
return getValue(handler);
|
return getValue(handler);
|
||||||
}
|
}
|
||||||
// create a new instance of the list element type
|
// create a new instance of the list element type
|
||||||
StringBuilder s = new StringBuilder();
|
StringBuilder s = new StringBuilder(300);
|
||||||
s.append("{");
|
s.append("{");
|
||||||
copyDataIntoStringBuilder(s, (CompoundTypeHandler) rootHandler);
|
copyDataIntoStringBuilder(s, (CompoundTypeHandler) rootHandler);
|
||||||
s.append("}");
|
s.append("}");
|
||||||
|
|
@ -303,7 +293,7 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String quote(String out) {
|
private static String quote(String out) {
|
||||||
StringBuilder s = new StringBuilder();
|
StringBuilder s = new StringBuilder(out.length() + 2);
|
||||||
out = s.append("\"").append(out).append("\"").toString();
|
out = s.append("\"").append(out).append("\"").toString();
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
@ -315,9 +305,9 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
||||||
compoundType.getProperties().forEach(property -> {
|
compoundType.getProperties().forEach(property -> {
|
||||||
if (property instanceof BuiltinTypeHandler) {
|
if (property instanceof BuiltinTypeHandler) {
|
||||||
BuiltinTypeHandler<?> typeHandler = (BuiltinTypeHandler<?>) property;
|
BuiltinTypeHandler<?> typeHandler = (BuiltinTypeHandler<?>) property;
|
||||||
String name = typeHandler.getName();
|
s.append(quote(typeHandler.getName()))
|
||||||
String value = getValue(typeHandler);
|
.append(": ")
|
||||||
s.append(quote(name)).append(": ").append(value);
|
.append(getValue(typeHandler));
|
||||||
} else {
|
} else {
|
||||||
CompoundTypeHandler p = (CompoundTypeHandler) property;
|
CompoundTypeHandler p = (CompoundTypeHandler) property;
|
||||||
s.append(p.getName()).append(":{");
|
s.append(p.getName()).append(":{");
|
||||||
|
|
@ -608,16 +598,14 @@ public class ContiguousList<E> extends NotImplementedList<E> implements List<E>
|
||||||
// used by SetterIterator
|
// used by SetterIterator
|
||||||
void extend() {
|
void extend() {
|
||||||
size += 1;
|
size += 1;
|
||||||
|
// keep track of index of element in data
|
||||||
|
elementIndices.add(bufferPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] getData() {
|
byte[] getData() {
|
||||||
return Arrays.copyOfRange(data.array(), 0, bufferPosition);
|
return Arrays.copyOfRange(data.array(), 0, bufferPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
int[] getElementIndices() {
|
|
||||||
return Arrays.copyOfRange(elementIndices, 0, size + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ensureFree(int length) {
|
private void ensureFree(int length) {
|
||||||
while (bufferPosition + length > data.capacity()) {
|
while (bufferPosition + length > data.capacity()) {
|
||||||
byte[] bytes = this.data.array();
|
byte[] bytes = this.data.array();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue