/*
* Copyright 2015 MiLaboratory.com
*
* 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 com.milaboratory.core.io.sequence;
import com.milaboratory.util.CanReportProgress;
/**
* Created by dbolotin on 23/06/14.
*/
public abstract class AbstractMultiReader<R extends SequenceRead>
extends AbstractSequenceReader<R> implements CanReportProgress,
SequenceReader<R>, SequenceReaderCloseable<R> {
private final SingleReader[] readers;
private final CanReportProgress[] progressReporters;
public AbstractMultiReader(SingleReader... readers) {
for (SingleReader reader : readers)
if (reader == null)
throw new NullPointerException();
this.readers = readers;
boolean crp = true;
for (SingleReader reader : readers)
crp &= reader instanceof CanReportProgress;
if (crp) {
progressReporters = new CanReportProgress[readers.length];
for (int i = 0; i < readers.length; i++)
progressReporters[i] = (CanReportProgress) readers[i];
} else
progressReporters = null;
}
protected synchronized SingleRead[] takeReads() {
SingleRead[] reads = new SingleRead[readers.length];
boolean hasNulls = false, allNulls = true;
for (int i = 0; i < reads.length; i++) {
reads[i] = readers[i].take();
hasNulls |= (reads[i] == null);
allNulls &= (reads[i] == null);
}
if (allNulls)
return null;
if (hasNulls)
throw new RuntimeException("Different number of reads in single-readers.");
// Incrementing reads counter
addOneRead();
return reads;
}
@Override
public void close() {
RuntimeException exception = null;
for (SingleReader reader : readers)
if (reader != null)
try {
reader.close();
} catch (RuntimeException e) {
exception = e;
}
if (exception != null)
throw exception;
}
@Override
public double getProgress() {
if (progressReporters == null)
return Double.NaN;
double sum = 0.0;
for (CanReportProgress reporter : progressReporters) {
double progress = reporter.getProgress();
if (Double.isNaN(progress))
return Double.NaN;
sum += progress;
}
return sum / progressReporters.length;
}
@Override
public boolean isFinished() {
if (progressReporters == null)
return true;
boolean allFinished = true;
for (CanReportProgress reporter : progressReporters)
allFinished &= reporter.isFinished();
return allFinished;
}
}