move creation of PdbWriter to the DataStore

This commit is contained in:
2019-02-07 18:06:41 +01:00
parent 58bfba23bb
commit ea5884a5e6
14 changed files with 87 additions and 66 deletions

View File

@@ -0,0 +1,10 @@
package org.lucares.pdb.datastore;
public class InvalidValueException extends IllegalArgumentException {
private static final long serialVersionUID = -8707541995666127297L;
public InvalidValueException(final String msg) {
super(msg);
}
}

View File

@@ -0,0 +1,94 @@
package org.lucares.pdb.datastore;
import java.io.IOException;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;
import org.lucares.collections.LongList;
import org.lucares.pdb.api.RuntimeIOException;
import org.lucares.pdb.api.Tags;
import org.lucares.pdb.blockstorage.BSFile;
import org.lucares.pdb.diskstorage.DiskStorage;
public class PdbFile {
private static class PdbFileToLongStream implements Function<PdbFile, Stream<LongList>> {
private final DiskStorage diskStorage;
public PdbFileToLongStream(final DiskStorage diskStorage) {
this.diskStorage = diskStorage;
}
@Override
public Stream<LongList> apply(final PdbFile pdbFile) {
try {
final BSFile bsFile = BSFile.existingFile(pdbFile.getRootBlockNumber(), diskStorage);
return bsFile.streamOfTimeValueLongLists();
} catch (final IOException e) {
throw new RuntimeIOException(e);
}
}
}
private final Tags tags;
/**
* The rootBlockNumber to be used by {@link BSFile}
*/
private final long rootBlockNumber;
public PdbFile(final long rootBlockNumber, final Tags tags) {
this.rootBlockNumber = rootBlockNumber;
this.tags = tags;
}
public Tags getTags() {
return tags;
}
public long getRootBlockNumber() {
return rootBlockNumber;
}
public static Stream<LongList> toStream(final List<PdbFile> pdbFiles, final DiskStorage diskStorage) {
final Stream<LongList> longStream = pdbFiles.stream().flatMap(new PdbFileToLongStream(diskStorage));
return longStream;
}
@Override
public String toString() {
return "PdbFile [tags=" + tags + ", rootBlockNumber=" + rootBlockNumber + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (rootBlockNumber ^ (rootBlockNumber >>> 32));
result = prime * result + ((tags == null) ? 0 : tags.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final PdbFile other = (PdbFile) obj;
if (rootBlockNumber != other.rootBlockNumber)
return false;
if (tags == null) {
if (other.tags != null)
return false;
} else if (!tags.equals(other.tags))
return false;
return true;
}
}

View File

@@ -0,0 +1,83 @@
package org.lucares.pdb.datastore;
import java.io.Flushable;
import java.io.IOException;
import java.util.Optional;
import org.lucares.pdb.api.Entry;
import org.lucares.pdb.blockstorage.BSFile;
import org.lucares.pdb.diskstorage.DiskStorage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
*/
public class PdbWriter implements AutoCloseable, Flushable {
private static final Logger LOGGER = LoggerFactory.getLogger(PdbWriter.class);
private final PdbFile pdbFile;
private long lastEpochMilli;
private final BSFile bsFile;
public PdbWriter(final PdbFile pdbFile, final DiskStorage diskStorage) throws IOException {
this.pdbFile = pdbFile;
bsFile = BSFile.existingFile(pdbFile.getRootBlockNumber(), diskStorage);
final Optional<Long> optionalLastValue = bsFile.getLastValue();
lastEpochMilli = optionalLastValue.orElse(0L);
}
public PdbFile getPdbFile() {
return pdbFile;
}
public long getDateOffsetAsEpochMilli() {
return lastEpochMilli;
}
public void write(final Entry entry) throws WriteException, InvalidValueException {
final long epochMilli = entry.getEpochMilli();
final long value = entry.getValue();
write(epochMilli, value);
}
private void write(final long epochMilli, final long value) throws WriteException, InvalidValueException {
try {
bsFile.appendTimeValue(epochMilli, value);
lastEpochMilli = epochMilli;
} catch (final IOException e) {
throw new WriteException(e);
}
}
@Override
public void close() {
LOGGER.debug("close PdbWriter {}", pdbFile);
bsFile.close();
}
@Override
public void flush() {
bsFile.flush();
}
public static void writeEntry(final PdbFile pdbFile, final DiskStorage diskStorage, final Entry... entries)
throws IOException {
try (PdbWriter writer = new PdbWriter(pdbFile, diskStorage)) {
for (final Entry entry : entries) {
writer.write(entry);
}
}
}
@Override
public String toString() {
return "PdbWriter [pdbFile=" + pdbFile + ", lastEpochMilli=" + lastEpochMilli + "]";
}
}

View File

@@ -0,0 +1,12 @@
package org.lucares.pdb.datastore;
import java.io.IOException;
public class ReadException extends RuntimeException {
private static final long serialVersionUID = 1L;
public ReadException(final IOException e) {
super(e);
}
}

View File

@@ -0,0 +1,18 @@
package org.lucares.pdb.datastore;
public class ReadRuntimeException extends RuntimeException {
private static final long serialVersionUID = 1L;
public ReadRuntimeException(final String message, final Throwable cause) {
super(message, cause);
}
public ReadRuntimeException(final String message) {
super(message);
}
public ReadRuntimeException(final Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,15 @@
package org.lucares.pdb.datastore;
public class WriteException extends RuntimeException {
private static final long serialVersionUID = 1L;
public WriteException(final String message, final Throwable cause) {
super(message, cause);
}
public WriteException(final Throwable cause) {
super(cause);
}
}

View File

@@ -9,6 +9,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -21,7 +22,11 @@ import org.lucares.pdb.api.Tag;
import org.lucares.pdb.api.Tags;
import org.lucares.pdb.blockstorage.BSFile;
import org.lucares.pdb.datastore.Doc;
import org.lucares.pdb.datastore.PdbFile;
import org.lucares.pdb.datastore.PdbWriter;
import org.lucares.pdb.datastore.Proposal;
import org.lucares.pdb.datastore.ReadException;
import org.lucares.pdb.datastore.WriteException;
import org.lucares.pdb.datastore.lang.Expression;
import org.lucares.pdb.datastore.lang.ExpressionToDocIdVisitor;
import org.lucares.pdb.datastore.lang.NewProposerParser;
@@ -42,6 +47,8 @@ public class DataStore implements AutoCloseable {
.getLogger("org.lucares.metrics.dataStore.executeQuery");
private static final Logger MAP_DOCS_TO_DOCID = LoggerFactory
.getLogger("org.lucares.metrics.dataStore.mapDocsToDocID");
private final static Logger METRICS_LOGGER_NEW_WRITER = LoggerFactory
.getLogger("org.lucares.metrics.dataStore.newPdbWriter");
private static final Logger LOGGER = LoggerFactory.getLogger(DataStore.class);
public static final char LISTING_FILE_SEPARATOR = ',';
@@ -330,15 +337,14 @@ public class DataStore implements AutoCloseable {
return result;
}
public List<Doc> getByTags(final Tags tags) {
public Optional<Doc> getByTags(final Tags tags) {
try {
final Long docId = tagsToDocId.getValue(tags);
final List<Doc> result = new ArrayList<>(0);
if (docId != null) {
final Doc doc = getDocByDocId(docId);
result.add(doc);
return Optional.of(doc);
}
return result;
return Optional.empty();
} catch (final IOException e) {
throw new RuntimeIOException(e);
}
@@ -375,4 +381,44 @@ public class DataStore implements AutoCloseable {
return diskStorage;
}
public PdbWriter getWriter(final Tags tags) {
final Optional<Doc> docsForTags = getByTags(tags);
PdbWriter writer;
if (docsForTags.isPresent()) {
try {
final Doc doc = docsForTags.get();
final PdbFile pdbFile = new PdbFile(doc.getRootBlockNumber(), tags);
writer = new PdbWriter(pdbFile, getDiskStorage());
} catch (final IOException e) {
throw new ReadException(e);
}
} else {
writer = newPdbWriter(tags);
}
return writer;
}
private PdbWriter newPdbWriter(final Tags tags) {
final long start = System.nanoTime();
try {
final PdbFile pdbFile = createNewPdbFile(tags);
final PdbWriter result = new PdbWriter(pdbFile, getDiskStorage());
METRICS_LOGGER_NEW_WRITER.debug("newPdbWriter took {}ms tags: {}",
(System.nanoTime() - start) / 1_000_000.0, tags);
return result;
} catch (final IOException e) {
throw new WriteException(e);
}
}
private PdbFile createNewPdbFile(final Tags tags) throws IOException {
final long rootBlockNumber = createNewFile(tags);
final PdbFile result = new PdbFile(rootBlockNumber, tags);
return result;
}
}