blob: 3091a9aec71e3f5fccfcd332e2d4cb347ba0c28b [file] [log] [blame]
package org.eclipse.stem.analysis.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.eclipse.stem.analysis.ScenarioInitializationException;
/*******************************************************************************
* Copyright (c) 2007, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
/**
* Adds methods for streaming data instead of loading all data files into memory
*/
public class CSVScenarioStreamer extends CSVscenarioLoader {
public static final int NUM_LEAD_COLS = 2;
Map<Integer, Map<String, BufferedReader>> streamReaders = new HashMap<Integer, Map<String, BufferedReader>>();
Map<Integer, Map<String, Integer>> streamReaderCurrentRow = new HashMap<Integer, Map<String, Integer>>();
Map<Integer, Map<String, List<Double>>> streamReadersLastRow = new HashMap<Integer, Map<String, List<Double>>>();
Map<Integer, List<String>> headersMap = new HashMap<Integer, List<String>>();
private int row = -1; // Which row
/**
* @param path
*/
public CSVScenarioStreamer(String path) throws ScenarioInitializationException {
super(path);
}
/**
* prepareForStreaming
*
* @param resolution The desired resolution, or -1 of all files should be streamed
*/
public void prepareForStreaming(int resolution) throws IOException {
for(int i = 0; i < diseaseData.size(); i ++) {
File f = diseaseData.get(i);
String name = f.getName();
if(f.getName().startsWith(".")) continue;//$NON-NLS-1$
int _idx = name.lastIndexOf('_');
int dotidx = name.lastIndexOf('.');
if(_idx <0 || dotidx < 0 || dotidx < _idx) continue; // not a data file
String state = name.substring(0, _idx);
// discovered a state
registerKey(state);
int res = Integer.parseInt(name.substring(_idx+1, dotidx));
if(resolution != -1 && res != resolution) continue; // wrong resolution
openFile(state, f, res);
}
}
/**
* openFile. Open data file and prepare for streaming
*
* @param state The state
* @param File file
* @param adminLevel
*/
public void openFile(String state, File f, int adminLevel) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(f));
if(!streamReaders.containsKey(adminLevel)) {
streamReaders.put(adminLevel, new HashMap<String, BufferedReader>());
streamReaderCurrentRow.put(adminLevel, new HashMap<String, Integer>());
streamReadersLastRow.put(adminLevel, new HashMap<String, List<Double>>());
}
Map<String, BufferedReader>stateReaderMap = streamReaders.get(adminLevel);
Map<String, Integer>stateRowMap = streamReaderCurrentRow.get(adminLevel);
Map<String, List<Double>>stateRowData = streamReadersLastRow.get(adminLevel);
stateReaderMap.put(state, reader);
stateRowMap.put(state, -1); // no row read yet, first row is row 0
stateRowData.put(state, null); // no data yet
String header;
if ( (header=reader.readLine()) != null ) {
if(!headersMap.containsKey(adminLevel)) {
List<String>headerElements = new ArrayList<String>();
headersMap.put(adminLevel, headerElements);
StringTokenizer st = new StringTokenizer(header, ",");//$NON-NLS-1$
int col = 0;
while (st.hasMoreTokens()) {
String val = st.nextToken().trim();
if(col < NUM_LEAD_COLS) {++col;continue;}
headerElements.add(val);
++col;
}
}
} // read the header
/////////////////////
}
/**
* streamRow Stream next row of data
*
*
* @param adminLevel which admin level
* @param state Which state (e.g. S)
* @return List<Double> The data, or null if end of line is encountered;
*/
public List<Double>streamRow(int adminLevel, String state) throws IOException {
BufferedReader br = streamReaders.get(adminLevel).get(state);
if(br == null) return null; // stream is closed
String data;
if ( (data=br.readLine()) != null ) {
if(streamReadersLastRow.get(adminLevel).get(state) == null)
streamReadersLastRow.get(adminLevel).put(state, new ArrayList<Double>());
List<Double>result = streamReadersLastRow.get(adminLevel).get(state);
result.clear();
StringTokenizer st = new StringTokenizer(data, ",");//$NON-NLS-1$
int col = 0;
while (st.hasMoreTokens()) {
String val = st.nextToken().trim();
if(col < NUM_LEAD_COLS) {++col;continue;}
result.add(Double.parseDouble(val));
++col;
}
streamReaderCurrentRow.get(adminLevel).put(state, streamReaderCurrentRow.get(adminLevel).get(state)+1);
return result;
}
br.close();
streamReaders.get(adminLevel).put(state, null);// gc reader
return null; // end of file reached
}
public int getCurrentRow(int adminLevel, String state) {
return streamReaderCurrentRow.get(adminLevel).get(state);
}
/**
* streamRow Stream next row of data
*
*
* @param adminLevel which admin level
* @param state Which state (e.g. S)
* @return List<Double> The data
*/
public List<Double>getLastFetchedRow(int adminLevel, String state) {
List<Double>result = streamReadersLastRow.get(adminLevel).get(state);
return result;
}
public int getDataPosition(int adminLevel, String key) {
return headersMap.get(adminLevel).indexOf(key);
}
}