replace ludb with data-store
LuDB has a few disadvantages.
1. Most notably disk space. H2 wastes a lot of valuable disk space.
For my test data set with 44 million entries it is 14 MB
(sometimes a lot more; depends on H2 internal cleanup). With
data-store it is 15 KB.
Overall I could reduce the disk space from 231 MB to 200 MB (13.4 %
in this example). That is an average of 4.6 bytes per entry.
2. Speed:
a) Liquibase is slow. The first time it takes approx. three seconds
b) Query and insertion. with data-store we can insert entries
up to 1.6 times faster.
Data-store uses a few tricks to save disk space:
1. We encode the tags into the file names.
2. To keep them short we translate the key/value of the tag into
shorter numbers. For example "foo" -> 12 and "bar" to 47. So the
tag "foo"/"bar" would be 12/47.
We then translate this number into a numeral system of base 62
(a-zA-Z0-9), so it can be used for file names and it is shorter.
That way we only have to store the mapping of string to int.
3. We do that in a simple tab separated file.
This commit is contained in:
7
pdb-ui/.gitignore
vendored
7
pdb-ui/.gitignore
vendored
@@ -1,6 +1,7 @@
|
||||
/bin/
|
||||
/build/
|
||||
/.settings/
|
||||
/test-output/
|
||||
/.classpath
|
||||
/.project
|
||||
/bin/
|
||||
/build/
|
||||
/target/
|
||||
/test-output/
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.lucares.pdbui;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@@ -20,7 +21,7 @@ public class MySpringConfiguration {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MySpringConfiguration.class);
|
||||
|
||||
@Bean
|
||||
PerformanceDb performanceDb(@Value("${db.base}") final String dbBaseDir) {
|
||||
PerformanceDb performanceDb(@Value("${db.base}") final String dbBaseDir) throws IOException {
|
||||
final Path dataDirectory = Paths.get(dbBaseDir);
|
||||
|
||||
LOGGER.info("using database in {}", dataDirectory.toAbsolutePath());
|
||||
|
||||
@@ -9,22 +9,22 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.lucares.ludb.FieldNotExistsException;
|
||||
import org.lucares.ludb.Proposal;
|
||||
import org.lucares.pdb.plot.api.PlotSettings;
|
||||
import org.lucares.pdbui.domain.AutocompleteProposal;
|
||||
import org.lucares.pdbui.domain.AutocompleteProposalByValue;
|
||||
import org.lucares.pdbui.domain.AutocompleteResponse;
|
||||
import org.lucares.pdbui.domain.PlotRequest;
|
||||
import org.lucares.pdbui.domain.PlotResponse;
|
||||
import org.lucares.performance.db.CollectionUtils;
|
||||
import org.lucares.performance.db.PerformanceDb;
|
||||
import org.lucares.performance.db.Proposal;
|
||||
import org.lucares.recommind.logs.DataSeries;
|
||||
import org.lucares.recommind.logs.InternalPlottingException;
|
||||
import org.lucares.recommind.logs.NoDataPointsException;
|
||||
import org.lucares.recommind.logs.PlotResult;
|
||||
import org.lucares.recommind.logs.Plotter;
|
||||
import org.lucares.utils.CollectionUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
@@ -41,7 +41,7 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
@Controller
|
||||
@EnableAutoConfiguration
|
||||
public class PdbController implements HardcodedValues, CollectionUtils {
|
||||
public class PdbController implements HardcodedValues {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(PdbController.class);
|
||||
|
||||
@@ -100,7 +100,7 @@ public class PdbController implements HardcodedValues, CollectionUtils {
|
||||
final int zeroBasedCaretIndex = caretIndex - 1;
|
||||
|
||||
final List<Proposal> proposals = db.autocomplete(query, zeroBasedCaretIndex);
|
||||
final List<Proposal> nonEmptyProposals = filter(proposals, p -> p.getResults() > 0);
|
||||
final List<Proposal> nonEmptyProposals = CollectionUtils.filter(proposals, p -> p.getResults() > 0);
|
||||
|
||||
final List<AutocompleteProposal> autocompleteProposals = toAutocompleteProposals(nonEmptyProposals);
|
||||
Collections.sort(autocompleteProposals, new AutocompleteProposalByValue());
|
||||
@@ -129,16 +129,12 @@ public class PdbController implements HardcodedValues, CollectionUtils {
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE //
|
||||
)
|
||||
@ResponseBody
|
||||
List<String> fields(@PathVariable(name = "fieldName") final String fieldName,
|
||||
SortedSet<String> fields(@PathVariable(name = "fieldName") final String fieldName,
|
||||
@RequestParam(name = "query") final String query) {
|
||||
|
||||
try {
|
||||
final List<String> fields = db.getFieldsValues(query, fieldName);
|
||||
final SortedSet<String> fields = db.getFieldsValues(query, fieldName);
|
||||
|
||||
return fields;
|
||||
} catch (final FieldNotExistsException e) {
|
||||
throw new NotFoundException(e);
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
private List<AutocompleteProposal> toAutocompleteProposals(final List<Proposal> proposals) {
|
||||
|
||||
@@ -159,7 +159,7 @@ public class TcpIngestor implements Ingestor, AutoCloseable, DisposableBean {
|
||||
}
|
||||
}
|
||||
|
||||
public TcpIngestor(final Path dataDirectory) {
|
||||
public TcpIngestor(final Path dataDirectory) throws IOException {
|
||||
LOGGER.info("opening performance db: " + dataDirectory);
|
||||
db = new PerformanceDb(dataDirectory);
|
||||
LOGGER.debug("performance db open");
|
||||
|
||||
@@ -14,8 +14,8 @@ import java.util.Map;
|
||||
|
||||
import org.lucares.pdb.api.Entry;
|
||||
import org.lucares.pdbui.TcpIngestor;
|
||||
import org.lucares.performance.db.FileUtils;
|
||||
import org.lucares.performance.db.PerformanceDb;
|
||||
import org.lucares.utils.file.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.testng.Assert;
|
||||
@@ -23,8 +23,6 @@ import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import liquibase.exception.LiquibaseException;
|
||||
|
||||
@Test
|
||||
public class TcpIngestorTest {
|
||||
|
||||
@@ -42,7 +40,7 @@ public class TcpIngestorTest {
|
||||
FileUtils.delete(dataDirectory);
|
||||
}
|
||||
|
||||
public void testIngestDataViaTcpStream() throws LiquibaseException, Exception {
|
||||
public void testIngestDataViaTcpStream() throws Exception {
|
||||
|
||||
final OffsetDateTime dateA = OffsetDateTime.now();
|
||||
final OffsetDateTime dateB = OffsetDateTime.now();
|
||||
|
||||
Reference in New Issue
Block a user