package com.xxx.xxx.query.version2;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.xxx.xxx.decode.MetaData;
import com.xxx.xxx.utils.DateFormatUtil;
public abstract class DataReader {
protected static Log log = LogFactory.getLog(DataReader.class);
protected static final int BUF_SIZE = 1024 * 4;
protected static final long MIN = 0L;
protected static final long MAX = 99999999999999L;
static final ThreadLocal<SimpleDateFormat> TL_DATE_FORMAT = DateFormatUtil.threadLocalDateFormat("yyyyMMddHHmmss");
public static long time_t2tick(long time_t, int clctDate){
long tick = 0L;
Date date = new Date(time_t * 1000);
DateFormat df = TL_DATE_FORMAT.get();
String str = df.format(date);
tick = Long.parseLong(str);
int clctYear = clctDate/10000;
int year = (int) (tick/10000000000L);
// System.out.println(clctYear + " " + year);
if(((clctYear - year) > 1)||((clctYear - year) < -1)){
long tail = tick%10000000000L;
long head = clctYear * 10000000000L;
tick = head + tail;
// System.out.println("tick " + tick);
}
return tick;
}
public abstract int getDataBuffSize();
public MetaData readTailRecord(String fileName, int date){
MetaData data = null;
int dataBuffSize = this.getDataBuffSize();
if(null != fileName && fileName.length() > 0 && dataBuffSize > 0){
File file = new File(fileName);
if(file.exists()){
long len = file.length();
long pos = len - dataBuffSize;
data = readSingleData(fileName, pos, date);
}
}
return data;
}
public MetaData readRecordByTick(String fileName, long tick, int date){
return binarySearchTick(fileName, tick, this.getDataBuffSize(), date);
}
protected MetaData readSingleData(String fileName, long pos, int date) {
MetaData data = null;
int dataBuffSize = this.getDataBuffSize();
if(null != fileName && fileName.length() > 0 && pos >= 0 && dataBuffSize > 0){
try {
byte[] buf = readBuf(fileName, pos, pos + dataBuffSize, dataBuffSize);
if(null != buf && buf.length == dataBuffSize){
@SuppressWarnings("unchecked")
List<MetaData> list = (List<MetaData>) this.decodeBody(buf, date);
if(null != list && list.size() > 0){
data = list.get(list.size() - 1);
}
}
} catch (Exception e) {
System.out.println(e);
}
}
return data;
}
protected MetaData binarySearchTick(String fileName, long tick, int dataSize, int date) {
MetaData data = null;
if(null != fileName && fileName.length() > 0 && tick > 0 && dataSize > 0){
File file = new File(fileName);
if(file.exists()){
int low = 0;
int high = (int)(file.length()/dataSize);
int hit = 0;
while(low <= high){
int mid = (low + high) / 2;
int midOffSet = mid * dataSize;
MetaData current = readSingleData(fileName, midOffSet, date);
if(null != current){
long midTick = current.getTick();
if(midTick < tick){
low = mid + 1;
}
else if(midTick > tick){
high = mid - 1;
}
else{
hit = mid;
data = current;
break;
}
}
hit = low - 1;
}
if(null == data && hit > 0){
// System.out.println("readSingleData " + fileName+ " " + hit * dataSize);
if(hit * dataSize == file.length())
{
hit--;
}
data = readSingleData(fileName, hit * dataSize, date);
}
}
}
return data;
}
protected final static byte[] readBuf(String filePath, long beginPos, long endPos, int buffSize){
byte[] buf = null;
File file = null;
RandomAccessFile raf = null;
if(null != filePath && filePath.length() > 0 && beginPos >= 0 && beginPos < endPos && buffSize > 0){
buf = new byte[buffSize];
try {
file = new File(filePath);
if(file.exists()){
raf = new RandomAccessFile(file, "r");
long size = raf.length();
if(endPos <= size){
raf.seek(beginPos);
raf.read(buf);
}
}
} catch (Throwable e) {
System.out.println(e);
} finally {
if (null != raf){
try {
raf.close();
} catch (IOException e) {
}
}
}
}
return buf;
}
protected List<? extends MetaData> decodeBody(byte[] buf, int date) throws Exception{
return this.decodeBody(buf, MIN, MAX, date);
}
protected abstract List<? extends MetaData> decodeBody(byte[] buf, long beginTime, long endTime, int date) throws Exception;
protected final static byte[] intToByte2(int n) {
byte[] bytes = new byte[2];
for (int i = 0; i < 2; i++) {
bytes[i] = (byte) (n % 256);
n = n >> 8;
}
return bytes;
}
protected final static byte[] intToByte4(long n) {
byte[] bytes = new byte[4];
for (int i = 0; i < 4; i++) {
bytes[i] = (byte) (n % 256);
n = n >> 8;
}
return bytes;
}
protected final static byte[] longToByte8(long n) {
byte[] bytes = new byte[8];
for (int i = 0; i < 8; i++) {
bytes[i] = (byte) (n % 256);
n = n >> 8;
}
return bytes;
}
protected final static short byte1ToShort(byte b) {
short n = 0;
if (b < 0) {
n = (short) (256 + b);
} else {
n = b;
}
return n;
}
protected final static int byte1ToInt(byte bt) {
int n = 0;
n = bt;
if (bt < 0)
n += 256;
return n;
}
protected final static int byte2ToInt(byte[] buf, int start) {
int n = 0;
if (null != buf) {
for (int i = 1; i >= 0; i--) {
n <<= 8;
n |= (buf[start + i] & 0x00ff);
}
}
return n;
}
protected final static long byte8ToLong(byte[] buf, int start) {
long n = 0;
try {
if (null != buf) {
for (int i = 7; i >= 0; i--) {
n <<= 8;
n |= (buf[start + i] & 0x000000ff);
}
}
} catch (Exception e) {
log.error(e);
}
return n;
}
protected final static int byte4ToInt(byte[] buf, int start) {
int n = 0;
try {
if (null != buf) {
for (int i = 3; i >= 0; i--) {
n <<= 8;
n |= (buf[start + i] & 0x000000ff);
}
}
} catch (Exception e) {
log.error(e);
}
return n;
}
}
package com.xxx.xxx.decode;
public abstract class MetaData
{
public long getTick()
{
return tick;
}
public void setTick(long tick)
{
this.tick = tick;
}
protected long tick;
}
package com.xxx.xxx.utils;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.TimeZone;
public class DateFormatUtil {
private static final String GMT_TIME_ZONE = "GMT+8:00".intern();
public static ThreadLocal<SimpleDateFormat> threadLocalDateFormat(final String pattern)
{
ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>() {
protected SimpleDateFormat initialValue() {
SimpleDateFormat df = new SimpleDateFormat(pattern, Locale.ENGLISH);
df.setTimeZone(TimeZone.getTimeZone(DateFormatUtil.GMT_TIME_ZONE));
return df;
}
};
return tl;
}
public static ThreadLocal<SimpleDateFormat> threadLocalDateFormat
(final String pattern, final TimeZone time_zone)
{
ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>()
{
protected SimpleDateFormat initialValue() {
SimpleDateFormat df = new SimpleDateFormat(pattern, Locale.ENGLISH);
df.setTimeZone(time_zone);
return df;
}
};
return tl;
}
}