/** * */ package com.github.seanlinwang.tkv.hdfs; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Comparator; import com.github.seanlinwang.tkv.local.RAFIndexStore; import com.github.seanlinwang.tkv.util.IoKit; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import com.github.seanlinwang.tkv.IndexStore; import com.github.seanlinwang.tkv.Meta; /** * @author sean.wang * @since Mar 7, 2012 */ public class HdfsIndexStore implements IndexStore { private RAFIndexStore localIndexStore; private FileSystem fs; private Path path; public HdfsIndexStore(FileSystem fs, String hdfsFilename, File localFile, int keyLength, int tagLength) throws IOException { this.fs = fs; //本地磁盘索引文件的存储方式是RAFIndexStore. this.localIndexStore = new RAFIndexStore(localFile, keyLength, tagLength); //还要在HDFS中存储一份.注意本地和HDFS的文件名是一样的,因为localFile的名称和这里的hdfsFilename一样 this.path = new Path(fs.getWorkingDirectory(), hdfsFilename); } @Override public void append(Meta meta) throws IOException { this.localIndexStore.append(meta); } @Override public void close() throws IOException { this.localIndexStore.close(); this.fs.close(); } @Override public boolean delete() throws IOException { boolean localDeleted = this.deleteLocal(); boolean remoteDeleted = this.deleteRemote(); return localDeleted && remoteDeleted; } public boolean deleteLocal() throws IOException { return this.localIndexStore.delete(); } public boolean deleteRemote() throws IOException { boolean remoteDeleted = false; if (this.fs != null) { remoteDeleted = this.fs.delete(path, false); } return remoteDeleted; } public void download() throws IOException { InputStream input = fs.open(path); OutputStream output = this.localIndexStore.getOutputStream(); IoKit.copyAndClose(input, output); } @Override public void flush() throws IOException { this.localIndexStore.flush(); //本地磁盘文件 InputStream input = this.localIndexStore.getInputStream(); //HDFS文件 OutputStream output = fs.create(path); //拷贝本地文件到HDFS上 IoKit.copyAndClose(input, output); } @Override public Meta getIndex(long indexPos) throws IOException { return this.localIndexStore.getIndex(indexPos); } @Override public Meta getIndex(String key) throws IOException { return this.localIndexStore.getIndex(key); } @Override public Meta getIndex(String key, Comparator<byte[]> keyComp) throws IOException { return this.localIndexStore.getIndex(key, keyComp); } @Override public Meta getIndex(String key, String tagName) throws IOException { return this.localIndexStore.getIndex(key, tagName); } @Override public Meta getIndex(String key, String tagName, Comparator<byte[]> keyComp) throws IOException { return this.localIndexStore.getIndex(key, tagName, keyComp); } @Override public int getIndexLength() { return this.localIndexStore.getIndexLength(); } @Override public long length() throws IOException { return this.localIndexStore.length(); } @Override public long size() throws IOException { return length() / getIndexLength(); } }