move creation of PdbWriter to the DataStore
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 + "]";
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user