/*
* Copyright (C) 2015 SoftIndex LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.datakernel.logfs;
import io.datakernel.async.CompletionCallback;
import io.datakernel.async.IgnoreCompletionCallback;
import io.datakernel.async.IgnoreResultCallback;
import io.datakernel.async.ResultCallback;
import io.datakernel.eventloop.Eventloop;
import io.datakernel.serializer.BufferSerializer;
import io.datakernel.util.Preconditions;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public final class LogManagerImpl<T> implements LogManager<T> {
public static final DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd_HH").withZone(DateTimeZone.UTC);
public static final DateTimeFormatter DETAILED_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd_HH-mm-ss").withZone(DateTimeZone.UTC);
public static final long DEFAULT_FILE_SWITCH_PERIOD = 60 * 60 * 1000L; // 1 hour
public static final int DEFAULT_BUFFER_SIZE = LogStreamConsumer.DEFAULT_BUFFER_SIZE;
public static final int DEFAULT_FLUSH_DELAY = LogStreamConsumer.DEFAULT_FLUSH_DELAY;
private final Eventloop eventloop;
private final LogFileSystem fileSystem;
private final BufferSerializer<T> serializer;
private final DateTimeFormatter dateTimeFormatter;
private final long fileSwitchPeriod;
private int bufferSize = DEFAULT_BUFFER_SIZE;
private int flushDelayMillis = DEFAULT_FLUSH_DELAY;
private LogManagerImpl(Eventloop eventloop, LogFileSystem fileSystem, BufferSerializer<T> serializer) {
this(eventloop, fileSystem, serializer, DEFAULT_DATE_TIME_FORMATTER, DEFAULT_FILE_SWITCH_PERIOD);
}
private LogManagerImpl(Eventloop eventloop, LogFileSystem fileSystem, BufferSerializer<T> serializer,
DateTimeFormatter dateTimeFormatter, long fileSwitchPeriod) {
this.eventloop = eventloop;
this.fileSystem = fileSystem;
this.serializer = serializer;
this.dateTimeFormatter = dateTimeFormatter;
this.fileSwitchPeriod = fileSwitchPeriod;
}
public static <T> LogManagerImpl<T> create(Eventloop eventloop, LogFileSystem fileSystem,
BufferSerializer<T> serializer) {
return new LogManagerImpl<T>(eventloop, fileSystem, serializer);
}
public static <T> LogManagerImpl<T> create(Eventloop eventloop, LogFileSystem fileSystem,
BufferSerializer<T> serializer, DateTimeFormatter dateTimeFormatter,
long fileSwitchPeriod) {
return new LogManagerImpl<T>(eventloop, fileSystem, serializer, dateTimeFormatter, fileSwitchPeriod);
}
public LogManagerImpl<T> fileSystemBufferSize(int bufferSize) {
this.bufferSize = bufferSize;
return this;
}
public LogManagerImpl<T> autoFlushDelayMillis(int flushDelayMillis) {
this.flushDelayMillis = flushDelayMillis;
return this;
}
@Override
public LogStreamConsumer<T> consumer(String logPartition) {
validateLogPartition(logPartition);
return consumer(logPartition, IgnoreCompletionCallback.create());
}
@Override
public LogStreamConsumer<T> consumer(String logPartition, CompletionCallback callback) {
validateLogPartition(logPartition);
LogStreamConsumer<T> logStreamConsumer = LogStreamConsumer.create(eventloop, fileSystem, serializer,
logPartition, dateTimeFormatter, fileSwitchPeriod, bufferSize, flushDelayMillis);
logStreamConsumer.setCompletionCallback(callback);
return logStreamConsumer;
}
@Override
public LogStreamProducer<T> producer(String logPartition, LogFile startLogFile, long startPosition,
ResultCallback<LogPosition> positionCallback) {
validateLogPartition(logPartition);
return LogStreamProducer.create(eventloop, fileSystem, serializer, logPartition,
LogPosition.create(startLogFile, startPosition), null, positionCallback);
}
@Override
public LogStreamProducer<T> producer(String logPartition, LogFile startLogFile, long startPosition,
LogFile endLogFile, ResultCallback<LogPosition> positionCallback) {
validateLogPartition(logPartition);
return LogStreamProducer.create(eventloop, fileSystem, serializer, logPartition,
LogPosition.create(startLogFile, startPosition), endLogFile,
positionCallback);
}
@Override
public LogStreamProducer<T> producer(String logPartition, long startTimestamp, long endTimestamp) {
validateLogPartition(logPartition);
return producer(logPartition, new LogFile(dateTimeFormatter.print(startTimestamp), 0), 0,
new LogFile(dateTimeFormatter.print(endTimestamp), 0),
IgnoreResultCallback.<LogPosition>create());
}
@Override
public LogStreamProducer<T> producer(String logPartition, String startLogFileName, String endLogFileName) {
validateLogPartition(logPartition);
return producer(logPartition, new LogFile(startLogFileName, 0), 0, new LogFile(endLogFileName, 0),
IgnoreResultCallback.<LogPosition>create());
}
private static void validateLogPartition(String logPartition) {
Preconditions.checkArgument(!logPartition.contains("-"), "Using dash (-) in log partition name is not allowed");
}
public DateTimeFormatter getDateTimeFormatter() {
return dateTimeFormatter;
}
}