package com.yahoo.glimmer.util;
/*
* Copyright (c) 2012 Yahoo! Inc. All rights reserved.
*
* 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.
* See accompanying LICENSE file.
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ReadersWriterMergeSort {
public static int mergeSort(List<BufferedReader> sourceReaders, Writer writer) throws IOException {
ReaderLineList sources = new ReaderLineList(sourceReaders.size());
for (BufferedReader reader : sourceReaders) {
ReaderLine readerLine = new ReaderLine(reader);
sources.insert(readerLine);
}
int count = 0;
String line;
while ((line = sources.readLine()) != null) {
writer.write(line);
writer.write('\n');
count++;
}
return count;
}
private static class ReaderLineList extends ArrayList<ReaderLine> {
private static final long serialVersionUID = 3646929636092521798L;
public ReaderLineList(int size) {
super(size);
}
public void insert(ReaderLine toInsert) {
if (toInsert.getLine() == null) {
return;
}
int insertIndex = Collections.binarySearch(this, toInsert);
if (insertIndex < 0) {
add(-insertIndex -1, toInsert);
} else {
throw new IllegalStateException("Duplicate line in input:" + toInsert.getLine());
}
}
public String readLine() throws IOException {
if (isEmpty()) {
return null;
}
ReaderLine readerLine = remove(size() - 1);
String line = readerLine.getLine();
if (readerLine.nextLine()) {
insert(readerLine);
}
return line;
}
}
private static class ReaderLine implements Comparable<ReaderLine> {
private final BufferedReader reader;
private String line;
public ReaderLine(BufferedReader reader) throws IOException {
this.reader = reader;
line = reader.readLine();
}
@Override
public int compareTo(ReaderLine that) {
return -this.line.compareTo(that.line);
}
public String getLine() {
return line;
}
public boolean nextLine() throws IOException {
if (line != null) {
line = reader.readLine();
if (line != null) {
return true;
}
}
return false;
}
}
}