package com.jivesoftware.os.amza.service.storage.delta;
import com.jivesoftware.os.amza.api.IoStats;
import com.jivesoftware.os.amza.api.wal.PrimaryRowMarshaller;
import com.jivesoftware.os.amza.api.wal.WALTx;
import com.jivesoftware.os.amza.service.storage.HighwaterRowMarshaller;
import com.jivesoftware.os.amza.service.storage.binary.BinaryWALTx;
import com.jivesoftware.os.amza.service.storage.binary.RowIOProvider;
import com.jivesoftware.os.jive.utils.ordered.id.OrderIdProvider;
import com.jivesoftware.os.mlogger.core.MetricLogger;
import com.jivesoftware.os.mlogger.core.MetricLoggerFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.mutable.MutableLong;
/**
* @author jonathan.colt
*/
public class DeltaWALFactory {
private static final MetricLogger LOG = MetricLoggerFactory.getLogger();
private final OrderIdProvider idProvider;
private final File walDir;
private final RowIOProvider ioProvider;
private final PrimaryRowMarshaller primaryRowMarshaller;
private final HighwaterRowMarshaller<byte[]> highwaterRowMarshaller;
private final long corruptionParanoiaFactor;
public DeltaWALFactory(OrderIdProvider idProvider,
File walDir,
RowIOProvider ioProvider,
PrimaryRowMarshaller primaryRowMarshaller,
HighwaterRowMarshaller<byte[]> highwaterRowMarshaller,
long corruptionParanoiaFactor) {
this.idProvider = idProvider;
this.walDir = walDir;
this.ioProvider = ioProvider;
this.primaryRowMarshaller = primaryRowMarshaller;
this.highwaterRowMarshaller = highwaterRowMarshaller;
this.corruptionParanoiaFactor = corruptionParanoiaFactor;
}
public DeltaWAL create(IoStats ioStats, long prevId) throws Exception {
return createOrOpen(ioStats, idProvider.nextId(), prevId);
}
private DeltaWAL createOrOpen(IoStats ioStats, long id, long prevId) throws Exception {
WALTx deltaWALRowsTx = new BinaryWALTx(
String.valueOf(prevId) + "_" + String.valueOf(id),
ioProvider,
primaryRowMarshaller,
Integer.MAX_VALUE,
64);
MutableLong rows = new MutableLong();
deltaWALRowsTx.open(
walDir,
io -> {
io.validate(ioStats, true, false,
(rowFP, rowTxId, rowType, row) -> {
rows.increment();
return (rows.longValue() < corruptionParanoiaFactor) ? -1 : rowFP;
},
(rowFP, rowTxId, rowType, row) -> -1,
null);
return null;
});
return new DeltaWAL(id, prevId, idProvider, primaryRowMarshaller, highwaterRowMarshaller, deltaWALRowsTx);
}
public List<DeltaWAL> list(IoStats ioStats) throws Exception {
List<DeltaWAL> deltaWALs = new ArrayList<>();
for (String filename : BinaryWALTx.listExisting(walDir, ioProvider)) {
try {
String[] parts = filename.split("_");
long prevId = Long.parseLong(parts[0]);
long id = Long.parseLong(parts[1]);
deltaWALs.add(createOrOpen(ioStats, id, prevId));
} catch (Exception x) {
LOG.warn("Encountered {} which doesn't conform to a WAL file naming conventions.", filename);
}
}
Collections.sort(deltaWALs);
return deltaWALs;
}
void destroy(DeltaWAL wal) throws Exception {
wal.destroy(walDir);
}
}