Initial commit

This commit is contained in:
2014-11-30 12:23:51 +00:00
commit 63c559ec90
56 changed files with 2543 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
package data;
import java.util.Date;
public class Entry {
public Date date;
public double value;
public Entry(Date date, double value) {
this.date = date;
this.value = value;
}
}

View File

@@ -0,0 +1,19 @@
package interval;
import java.util.Calendar;
import java.util.Date;
public class Day extends Minute {
public Day() {}
public Date next() {
calendar.add(Calendar.DAY_OF_MONTH, 1);
return get();
}
protected void adjust() {
super.adjust();
calendar.set(Calendar.HOUR_OF_DAY, 0);
}
}

View File

@@ -0,0 +1,20 @@
package interval;
import java.util.Calendar;
import java.util.Date;
public class Hour extends Minute {
public static final int HOURS = 1;
public Hour() {}
public Date next() {
calendar.add(Calendar.HOUR, HOURS);
return get();
}
protected void adjust() {
super.adjust();
calendar.set(Calendar.MINUTE, 0);
}
}

View File

@@ -0,0 +1,7 @@
package interval;
public class Hour12 extends Hour {
public static final int HOURS = 12;
public Hour12() {}
}

View File

@@ -0,0 +1,8 @@
package interval;
public class Hour2 extends Hour {
public static final int HOURS = 2;
public Hour2() {}
}

View File

@@ -0,0 +1,7 @@
package interval;
public class Hour4 extends Hour {
public static final int HOURS = 4;
public Hour4() {}
}

View File

@@ -0,0 +1,7 @@
package interval;
public class Hour6 extends Hour {
public static final int HOURS = 6;
public Hour6() {}
}

View File

@@ -0,0 +1,54 @@
package interval;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.TimeZone;
public abstract class Interval implements Iterator<Date> {
public static final String TIMEZONE = "Europe/Amsterdam";
protected Date endDate;
protected TimeZone timeZone;
protected Calendar calendar;
public Interval() {}
public Interval(Date startDate, Date endDate, String timeZoneID) {
setTimeZone(timeZoneID);
setDate(startDate, endDate);
}
public void setTimeZone(String timeZoneID) {
timeZone = TimeZone.getTimeZone(timeZoneID);
calendar = new GregorianCalendar(TimeZone.getTimeZone(TIMEZONE));
}
public Interval(Date startDate, Date endDate) {
this(startDate, endDate, TIMEZONE);
}
public void setDate(Date startDate, Date endDate) {
if (timeZone == null) {
setTimeZone(TIMEZONE);
}
calendar.setTime(startDate);
adjust();
this.endDate = endDate;
}
public void remove() {}
public Date get() {
return calendar.getTime();
}
public abstract Date next();
public boolean hasNext() {
return next().compareTo(endDate) < 0;
}
protected abstract void adjust();
}

View File

@@ -0,0 +1,18 @@
package interval;
import java.util.Calendar;
import java.util.Date;
public class Minute extends Interval {
public static final int MINUTES = 1;
public Date next() {
calendar.add(Calendar.MINUTE, MINUTES);
return get();
}
protected void adjust() {
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
}
}

View File

@@ -0,0 +1,7 @@
package interval;
public class Minute15 extends Minute {
public static final int MINUTES = 15;
public Minute15() {}
}

View File

@@ -0,0 +1,7 @@
package interval;
public class Minute30 extends Minute {
public static final int MINUTES = 30;
public Minute30() {}
}

View File

@@ -0,0 +1,18 @@
package interval;
import java.util.Date;
import java.util.Calendar;
public class Month extends Day {
public Month() {}
public Date next() {
calendar.add(Calendar.MONTH, 1);
return get();
}
protected void adjust() {
super.adjust();
calendar.set(Calendar.DAY_OF_MONTH, 1);
}
}

View File

@@ -0,0 +1,18 @@
package interval;
import java.util.Calendar;
import java.util.Date;
public class Week extends Day {
public Week() {}
public Date next() {
calendar.add(Calendar.WEEK_OF_MONTH, 1);
return get();
}
protected void adjust() {
super.adjust();
calendar.set(Calendar.DAY_OF_WEEK, 2);
}
}

View File

@@ -0,0 +1,306 @@
package model;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.json.simple.JSONArray;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.SortingParams;
import redis.clients.jedis.Transaction;
import redis.clients.util.SafeEncoder;
import util.DateUtils;
import util.StringUtils;
import data.Entry;
public class Model {
public static final int BATCH_SIZE = 10;
protected Calendar calendar;
protected JedisPool pool;
protected Jedis jedis;
protected Transaction transaction;
protected int insertDataBatchCount, insertExtremesBatchStatementCount;
protected PreparedStatement insertDataBatchStatement, insertExtremesBatchStatement;
//private Pipeline pipeline;
public Model(Calendar calendar) {
this.calendar = calendar;
pool = new JedisPool("localhost", 16379);
jedis = pool.getResource();
jedis.select(1);
//clear();
}
public void clear() {
Set<String> set = jedis.keys("*");
if (set.size() > 0) {
jedis.del(set.toArray(new String[0]));
}
}
public void createDataTable() throws SQLException {
}
public void createIntervalsTable() throws SQLException {
}
public void createExtremesTable() throws SQLException {
}
public Date getFirstEntryDate() throws SQLException {
List<String> list = jedis.sort("data", new SortingParams().limit(1, 1));
long timestamp = 0;
if (list.size() > 0) {
timestamp = Long.valueOf(list.get(0));
}
calendar.setTimeInMillis(1000 * timestamp);
return calendar.getTime();
}
public Date getLastEntryDate() throws SQLException {
List<String> list = jedis.sort("data", new SortingParams().limit(1, 1).desc());
long timestamp = 0;
if (list.size() > 0) {
timestamp = Long.valueOf(list.get(0));
}
calendar.setTimeInMillis(1000 * timestamp);
return calendar.getTime();
}
public void insertInterval(String name) throws SQLException {
Long id = jedis.incr("global:next-interval-id");
String parameter = StringUtils.parameterize(name);
jedis.set(String.format("interval:%d:name", id), name);
jedis.set(String.format("interval:%s:id", parameter), String.valueOf(id));
}
public int selectIntervalId(String name) throws Exception {
String parameter = StringUtils.parameterize(name);
return Integer.valueOf(jedis.get(String.format("interval:%s:id", parameter)));
}
public ArrayList<Entry> selectDataBetween(Date intervalStartDate, Date intervalEndDate) {
// PreparedStatement selectStatement = connection.prepareStatement("select * from data where date between ? and ?");
// selectStatement.setLong(1, intervalStartDate.getTime() / 1000);
// selectStatement.setLong(2, intervalEndDate.getTime() / 1000);
// ResultSet resultSet = selectStatement.executeQuery();
long min = intervalStartDate.getTime() / 1000;
long max = intervalEndDate.getTime() / 1000;
String key = String.format("data:%s:%s", min, max);
Set<String> dateSet = jedis.zrangeByScore("data", min, max);
String[] dateArray = dateSet.toArray(new String[0]);
ArrayList<Entry> entryList = new ArrayList<Entry>();
if (dateArray.length == 0) {
return entryList;
}
jedis.sadd(SafeEncoder.encode(key), SafeEncoder.encodeMany(dateArray));
List<String> valueList = jedis.sort(key, new SortingParams().nosort().get("data:*:value"));
Iterator<String> iterator = dateSet.iterator();
int i = 0;
while (iterator.hasNext()) {
calendar.setTimeInMillis(1000 * Long.valueOf(iterator.next()));
entryList.add(new Entry(calendar.getTime(), Double.valueOf(valueList.get(i++))));
}
return entryList;
}
public void insertDataBatch(long date, double value) throws SQLException {
// if (pipeline == null) {
// pipeline = jedis.pipelined();
// pipeline.multi();
// }
// if (insertDataBatchStatement == null) {
// insertDataBatchStatement = connection.prepareStatement("insert or ignore into data values(?, ?)");
// insertDataBatchCount = 0;
// }
// setDate(insertDataBatchStatement, 1, date);
// insertDataBatchStatement.setDouble(2, value);
// insertDataBatchStatement.addBatch();
//
// if(++insertDataBatchCount % BATCH_SIZE == 0) {
// insertDataBatchStatement.executeBatch();
// System.out.println(insertDataBatchCount);
// }
date /= 1000;
jedis.zadd(String.format("data"), date, String.valueOf(date));
jedis.set(String.format("data:%s:value", date), String.valueOf(value));
}
public void insertDataBatchLast() throws SQLException {
//pipeline.exec();
//pipeline = null;
}
public void insertExtremesBatch(int id, Date date, Date firstDate, Date lastDate, int count, Double min, Double max) throws SQLException {
// if (pipeline == null) {
// pipeline = jedis.pipelined();
// pipeline.multi();
// }
// HashMap<String, String> map = new HashMap<String, String>();
// map.put("first", String.valueOf(firstDate.getTime() / 1000));
// map.put("last", String.valueOf(lastDate.getTime() / 1000));
// map.put("count", String.valueOf(count));
// map.put("min", String.valueOf(min));
// map.put("max", String.valueOf(max));
int dateInt = (int) date.getTime() / 1000;
String key = String.format("extreme:%d:%d:", id, dateInt);
jedis.set(key + "first", String.valueOf(firstDate.getTime() / 1000));
jedis.set(key + "last", String.valueOf(lastDate.getTime() / 1000));
jedis.set(key + "count", String.valueOf(count));
jedis.set(key + "min", String.valueOf(min));
jedis.set(key + "max", String.valueOf(max));
jedis.zadd(String.format("interval:%d", id), dateInt, String.valueOf(dateInt));
//jedis.hmset(String.format("extreme:%d:%d", id, date.getTime() / 1000), map);
if(++insertExtremesBatchStatementCount % BATCH_SIZE == 0) {
//pipeline.exec();
//pipeline.multi();
System.out.println(insertExtremesBatchStatementCount);
}
}
public void insertExtremesBatchLast() throws SQLException {
//pipeline.exec();
//pipeline = null;
}
protected void listData() throws SQLException {
// ResultSet resultSet = statement.executeQuery("select *,datetime(date, 'unixepoch') as fmt from data");
// while (resultSet.next()) {
// System.out.println("--------------------------");
// System.out.println("date = " + resultSet.getString("date"));
// System.out.println("value = " + resultSet.getFloat("value"));
// System.out.println("format = " + resultSet.getString("fmt"));
// }
}
protected String getField(ResultSet resultSet, String columnLabel) throws SQLException {
return resultSet.getString(columnLabel);
}
protected void printField(ResultSet resultSet, String columnLabel) throws SQLException {
System.out.printf("%s = %s\n", columnLabel, resultSet.getString(columnLabel));
}
protected void setDate(PreparedStatement statement, int parameterIndex, Date date) throws SQLException {
setDate(statement, parameterIndex, date.getTime());
}
protected void setDate(PreparedStatement statement, int parameterIndex, long date) throws SQLException {
statement.setLong(parameterIndex, date / 1000);
}
public ResultSet getExtremes(long startDate, long endDate, String name) throws SQLException {
// PreparedStatement selectStatement = connection.prepareStatement(
// "select extremes.date date, extremes.first date_first, extremes.last date_last, extremes.count count, extremes.min min_value, extremes.max max_value, first.value first_value, last.value last_value " +
// "from extremes " +
// "left join data first on extremes.first = first.date " +
// "left join data last on extremes.last = last.date " +
// "where interval_id = (select id from intervals where name = ?) and extremes.date between ? and ?");
// selectStatement.setString(1, name);
// setDate(selectStatement, 2, startDate);
// setDate(selectStatement, 3, endDate);
// return selectStatement.executeQuery();
return null;
}
@SuppressWarnings("unchecked")
public String getJSON(long startDate, long endDate, String name) throws SQLException {
ResultSet resultSet = getExtremes(
DateUtils.makeTimestamp(2012, 1, 1, 14, 0, 0, 0),
DateUtils.makeTimestamp(2013, 7, 1, 14, 0, 0, 0), "Day");
JSONArray jsonList = new JSONArray();
while (resultSet.next()) {
JSONArray jsonEntry = new JSONArray();
jsonEntry.add(1000 * resultSet.getLong("date"));
jsonEntry.add(resultSet.getDouble("first_value"));
jsonEntry.add(resultSet.getDouble("min_value"));
jsonEntry.add(resultSet.getDouble("max_value"));
jsonEntry.add(resultSet.getDouble("last_value"));
jsonList.add(jsonEntry);
}
return jsonList.toJSONString();
}
public void test(long startDate, long endDate, String name) throws SQLException {
ResultSet resultSet = getExtremes(startDate, endDate, name);
while (resultSet.next()) {
System.out.println("----------------");
System.out.printf("# %d\n", resultSet.getRow());
printField(resultSet, "date");
printField(resultSet, "date_first");
printField(resultSet, "count");
printField(resultSet, "min_value");
printField(resultSet, "max_value");
printField(resultSet, "first_value");
printField(resultSet, "last_value");
}
}
public void test() {
/*Transaction transaction = jedis.multi();
Pipeline pipeline = jedis.pipelined();
Client client = jedis.getClient();*/
// ZRANGEBYSCORE data 1375085460 1375088460
// SORT data BY NOSORT GET data:*:value
int min = 1375085460;
int max = 1375088460;
String key = String.format("data:%s:%s", min, max);
Set<String> set = jedis.zrangeByScore("data", min, max);
jedis.sadd(SafeEncoder.encode(key), SafeEncoder.encodeMany(set.toArray(new String[0])));
List<String> list = jedis.sort(key, new SortingParams().nosort().get("data:*:value"));
for (String string : list) {
System.out.println(string);
}
Map<String, String> a = jedis.hgetAll("extreme:2");
System.out.println(a.get("date"));
//jedis.sort(date, new SortingParams().nosort().get("extreme:*"));
//set = jedis.zrange("interval:1", 0, -1);
min = 0;
max = Integer.MAX_VALUE;
key = String.format("interval:1:%s:%s", min, max);
set = jedis.zrangeByScore("interval:1", min, max);
jedis.sadd(SafeEncoder.encode(key), SafeEncoder.encodeMany(set.toArray(new String[0])));
list = jedis.sort(key, new SortingParams().nosort().get(new String[] {
"extreme:1:*:count",
"extreme:1:*:first"}));
//Iterator<String> iterator = set.iterator();
for (String string : list) {
System.out.println(string);
}
}
}

View File

@@ -0,0 +1,44 @@
package util;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class DateUtils {
public static final String TIMEZONE = "Europe/Amsterdam";
protected static TimeZone timeZone;
protected static Calendar calendar;
public static void setTimeZone(String timeZone) {
DateUtils.timeZone = TimeZone.getTimeZone(timeZone);
calendar = new GregorianCalendar(DateUtils.timeZone);
}
public static long makeTimestamp(int year, int month, int day, int hour, int minute, int second, int millisecond) {
checkCalendar();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month - 1);
calendar.set(Calendar.DATE, day);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, second);
calendar.set(Calendar.MILLISECOND, millisecond);
return calendar.getTimeInMillis();
}
public static TimeZone getTimeZone() {
checkCalendar();
return timeZone;
}
public static Calendar getCalendar() {
checkCalendar();
return calendar;
}
protected static void checkCalendar() {
if (calendar == null ) {
setTimeZone(TIMEZONE);
}
}
}

View File

@@ -0,0 +1,84 @@
package util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Scanner;
public class FileUtils {
public static final boolean REVERSE = false;
public static String resourceToString(String name) throws IOException {
File file = resourceToFile(name);
Scanner scanner = new Scanner(file);
String string = scanner.useDelimiter("\\A").next();
scanner.close();
return string;
}
public static File resourceToFile(String name) throws IOException {
URL url = ClassLoader.getSystemClassLoader().getResource(name);
if (url != null) {
try {
return new File(url.toURI());
} catch (URISyntaxException e) {}
}
throw new IOException();
}
public static BufferedReader resourceToReader(String name) throws IOException {
return resourceToReader(name, REVERSE);
}
public static BufferedReader resourceToReader(String name, boolean reverse) throws IOException {
File file = resourceToFile(name);
return fileToReader(file, reverse);
}
public static BufferedReader fileToBufferedReader(File file) throws FileNotFoundException {
return fileToReader(file, REVERSE);
}
public static BufferedReader fileToReader(File file, boolean reverse) throws FileNotFoundException {
InputStream inputStream = fileToInputStream(file, reverse);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
return new BufferedReader(inputStreamReader);
}
public static InputStream fileToInputStream(File file) throws FileNotFoundException {
return fileToInputStream(file, REVERSE);
}
public static InputStream fileToInputStream(File file, boolean reverse) throws FileNotFoundException {
InputStream inputStream;
if (reverse) {
inputStream = new ReverseLineInputStream(file);
} else {
inputStream = new FileInputStream(file);
}
return inputStream;
}
public static InputStream resourceToInputStream(String name) throws IOException {
return resourceToInputStream(name, REVERSE);
}
public static InputStream resourceToInputStream(String name, boolean reverse) throws IOException {
if (reverse) {
File file = resourceToFile(name);
return fileToInputStream(file, reverse);
} else {
return ClassLoader.getSystemClassLoader().getResourceAsStream(name);
}
}
public static Scanner resourceToScanner(String string) throws IOException {
return new Scanner(resourceToReader(string));
}
}

View File

@@ -0,0 +1,190 @@
package util;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.codec.digest.DigestUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisDataException;
public class LuaUtils {
public static final boolean LOAD = true;
public static final List<String> EMPTY = new ArrayList<String>();
public static final String[] LIBRARY_ARRAY = {"redis", "table", "string", "math", "debug", "cjson", "cmsgpack"};
public static final List<String> LIBRARY_LIST = Arrays.asList(LIBRARY_ARRAY);
protected static JedisPool jedisPool;
protected static HashMap<String, String> hashMap = new HashMap<String, String>();
public static void setPool(JedisPool pool) {
LuaUtils.jedisPool = pool;
}
public static Object eval(String name, List<String> keys, List<String> args) throws IOException {
Jedis jedis = jedisPool.getResource();
String hash = getHash(name, jedis);
System.out.println(hash);
Object object = jedis.evalsha(hash, keys, args);
jedisPool.returnResource(jedis);
return object;
}
public static Object eval(String name, int keys, String... args) throws IOException {
Jedis jedis = getResource();
String hash = getHash(name, jedis);
try {
return jedis.evalsha(hash, keys, args);
} catch (JedisDataException e) {
if (e.getMessage().startsWith("NOSCRIPT")) {
// Script not loaded correctly
}
System.out.println(e);
throw e;
} finally {
returnResource(jedis);
}
}
public static Object eval(String name) throws IOException {
return eval(name, 0);
}
public static Object eval(String string, List<String> params) throws IOException {
return eval(string, EMPTY, params);
}
protected static String getHash(String name, Jedis jedis) throws IOException {
name = String.format("%s.lua", name);
if (hashMap.containsKey(name)) {
return hashMap.get(name);
} else {
String lua = FileUtils.resourceToString(name);
Map<String, List<String>> libraryMap = new HashMap<String, List<String>>();
lua = resolveDepencencies(lua, libraryMap);
for (String library : libraryMap.keySet()) {
lua = String.format("local %s = {}\n%s", library, lua);
}
System.out.println("======");
System.out.println(lua);
System.out.println("======");
String hash = DigestUtils.sha1Hex(lua);
if (!jedis.scriptLoad(lua).equals(hash)) {
// Hashes don't match
}
hashMap.put(name, hash);
return hash;
}
}
protected static String resolveDepencencies(String lua, Map<String, List<String>> libraryMap) throws IOException {
Pattern pattern = Pattern.compile(String.format("([a-z]+)%s([a-z]+)", Pattern.quote(".")));
Matcher matcher = pattern.matcher(lua);
String depencencyLua = "";
while (matcher.find()) {
String library = matcher.group(1);
if (!LIBRARY_LIST.contains(library)) {
if (!libraryMap.containsKey(library)) {
libraryMap.put(library, new ArrayList<String>());
}
List<String> methodList = libraryMap.get(library);
String method = matcher.group(2);
if (!methodList.contains(method)) {
String file = String.format("%s/%s.lua", library, method);
System.out.println(file);
String methodLua = FileUtils.resourceToString(file);
methodList.add(method);
String subDepencencyLua = resolveDepencencies(methodLua, libraryMap);
if (depencencyLua.isEmpty()) {
depencencyLua = subDepencencyLua;
} else if (!subDepencencyLua.isEmpty()) {
depencencyLua = String.format("%s\n%s", depencencyLua, subDepencencyLua);
}
}
}
}
if (depencencyLua.isEmpty()) {
return lua;
} else {
return String.format("%s\n%s", depencencyLua, lua);
}
}
protected static void returnResource(Jedis jedis) {
jedisPool.returnResource(jedis);
}
protected static Jedis getResource() {
return jedisPool.getResource();
}
public static Object insert(String table, Map<String, String> hash) throws IOException {
List<String> params = new ArrayList<String>();
for (final Entry<String, String> entry : hash.entrySet()) {
params.add(entry.getKey());
params.add(entry.getValue());
params.add(StringUtils.parameterize(entry.getValue()));
}
params.add(0, table);
return LuaUtils.eval("insert", params);
}
@SuppressWarnings("unchecked")
public static List<Map<String, String>> getAll(String table) throws IOException {
List<String> params = new ArrayList<String>();
params.add(table);
List<List<String>> listList = (List<List<String>>) LuaUtils.eval("getall", params);
List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
System.out.println(listList.size());
for (List<String> list : listList) {
mapList.add(TypeUtils.listToMap(list));
}
return mapList;
}
@SuppressWarnings("unchecked")
public static List<Map<String, String>> getSome(String... stringArray) throws IOException {
List<List<String>> listList = (List<List<String>>) LuaUtils.eval("getsome", Arrays.asList(stringArray));
List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
for (List<String> list : listList) {
Map<String, String> map = new HashMap<String, String>();
for (int i = 1; i < stringArray.length; ++i) {
map.put(stringArray[i], list.get(i - 1));
}
mapList.add(map);
}
return mapList;
}
@SuppressWarnings("unchecked")
public static List<Map<String, String>> getSomeX(String... stringArray) throws IOException {
List<String> list = (List<String>) LuaUtils.eval("getsomex", Arrays.asList(stringArray));
Iterator<String> iterator = list.iterator();
List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
while (iterator.hasNext()) {
Map<String, String> map = new HashMap<String, String>();
for (int i = 1; i < stringArray.length; ++i) {
map.put(stringArray[i], iterator.next());
}
mapList.add(map);
}
return mapList;
}
}

View File

@@ -0,0 +1,68 @@
package util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
public class ReverseLineInputStream extends InputStream {
RandomAccessFile randomAccessFile;
long currentLineStart = -1;
long currentLineEnd = -1;
long currentPos = -1;
long lastPosInFile = -1;
public ReverseLineInputStream(File file) throws FileNotFoundException {
randomAccessFile = new RandomAccessFile(file, "r");
currentLineStart = file.length();
currentLineEnd = file.length();
lastPosInFile = file.length() - 1;
currentPos = currentLineEnd;
}
public void findPrevLine() throws IOException {
currentLineEnd = currentLineStart;
// No more lines, since at the beginning of the file
if (currentLineEnd == 0) {
currentLineEnd = -1;
currentLineStart = -1;
currentPos = -1;
return;
}
long filePointer = currentLineStart - 1;
while (true) {
// At start of file so this is the first line in the file.
if (--filePointer < 0) {
break;
}
randomAccessFile.seek(filePointer);
int readByte = randomAccessFile.readByte();
// Ignore last LF in file. search back to find the previous LF.
if (readByte == 0xA && filePointer != lastPosInFile) {
break;
}
}
// Start at pointer +1, after the LF found or at 0 the start of the file.
currentLineStart = filePointer + 1;
currentPos = currentLineStart;
}
public int read() throws IOException {
if (currentPos < currentLineEnd) {
randomAccessFile.seek(currentPos++);
int readByte = randomAccessFile.readByte();
return readByte;
} else if (currentPos < 0) {
return -1;
} else {
findPrevLine();
return read();
}
}
}

View File

@@ -0,0 +1,19 @@
package util;
import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
public class StringUtils {
protected static final char SEPARATOR = '-';
public static String parameterize(String input) {
return parameterize(input, SEPARATOR);
}
public static String parameterize(String input, char separator) {
Splitter splitter = Splitter.on(CharMatcher.JAVA_LETTER_OR_DIGIT.negate()).omitEmptyStrings();
Joiner joiner = Joiner.on(separator);
return joiner.join(splitter.split(input)).toLowerCase();
}
}

View File

@@ -0,0 +1,17 @@
package util;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class TypeUtils {
public static <T> Map<T,T> listToMap(List<T> list) {
Map<T, T> map = new HashMap<T, T>();
Iterator<T> iterator = list.iterator();
while (iterator.hasNext()) {
map.put(iterator.next(), iterator.next());
}
return map;
}
}