package org.commoncrawl.service.statscollector;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.io.BytesWritable;
import org.commoncrawl.async.EventLoop;
import org.commoncrawl.util.TimeSeriesDataFile;
public class StatsLogManager {
private static class DiskIORequest {
DiskIORequest(Runnable runnable) {
_runnable = runnable;
}
public Runnable _runnable;
}
private EventLoop _eventLoop;
private File _workingDirectory;
private Map<String,TimeSeriesDataFile<BytesWritable>> _nameToFileMap = new TreeMap<String,TimeSeriesDataFile<BytesWritable>>();
private Thread _diskThread = null;
private LinkedBlockingQueue<DiskIORequest> _requestQueue = new LinkedBlockingQueue<DiskIORequest>();
private static final Log LOG = LogFactory.getLog(StatsLogManager.class);
/**
* Constructor
*
* @param serverEventLoop
* @param workingDirectory
*/
public StatsLogManager(EventLoop serverEventLoop,File workingDirectory) throws IOException {
_eventLoop = serverEventLoop;
_workingDirectory = workingDirectory;
_diskThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
DiskIORequest request = _requestQueue.take();
if (request._runnable != null) {
request._runnable.run();
}
else {
break;
}
} catch (InterruptedException e) {
}
}
}
});
_diskThread.start();
}
/**
* initiate a proper shtudown
*/
public void shutdown() {
if (_diskThread != null) {
try {
_requestQueue.put(new DiskIORequest(null));
_diskThread.join();
_diskThread = null;
} catch (InterruptedException e) {
}
}
}
/** queue a disk io request
*
*/
public void queueDiskIORequest(Runnable runnable) {
try {
_requestQueue.put(new DiskIORequest(runnable));
} catch (InterruptedException e) {
}
}
/**
*
* @param groupKey
* @param uniqueKey
* @param fileType
* @return TimeSeriesDataFile object associated with the given composite key
*/
public synchronized TimeSeriesDataFile<BytesWritable> getFileGivenName(String groupKey,String uniqueKey,String fileType) {
File filePath = makePath(groupKey,uniqueKey,fileType);
TimeSeriesDataFile<BytesWritable> fileOut = _nameToFileMap.get(filePath.getName());
if (fileOut == null) {
fileOut = new TimeSeriesDataFile<BytesWritable>(filePath,BytesWritable.class);
_nameToFileMap.put(filePath.getName(),fileOut);
}
return fileOut;
}
/**
* Make a unique collection name given a group key and a unique collection key
*
* @param groupKey the group key
* @param uniqueKey the unique key
* @return
*/
public static String makeCollectionName(String groupKey,String uniqueKey) {
return groupKey+"-"+uniqueKey;
}
public static String getUniqueKeyGivenName(String collectionName) {
int indexOfDash = collectionName.indexOf('-');
return collectionName.substring(indexOfDash + 1);
}
public EventLoop getEventLoop() {
return _eventLoop;
}
private File makePath(String groupKey,String uniqueKey,String fileType) {
String compositeName = makeCollectionName(groupKey,uniqueKey) +"." + fileType;
return new File(_workingDirectory,compositeName);
}
}