package org.ripple.power.database; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import org.ripple.power.NativeSupport; import org.ripple.power.config.LSystem; import org.ripple.power.utils.FileUtils; public class AddressDataBase { private HashMap<String, FileWriter> pPutAddress = new HashMap<String, FileWriter>( 1000); private boolean isOnlyLocked = false; protected final static String pIndexName = "index"; private int pMaxCache = 300; private String pDirPath = ""; public AddressDataBase(String dir) { this.pDirPath = dir; } public int getMaxCache() { return pMaxCache; } public void setMaxCache(int max) { this.pMaxCache = max; } public String getDirPath() { return pDirPath; } public void setDirPath(String path) { this.pDirPath = path; } public boolean isOnlyLocked() { return isOnlyLocked; } public void setOnlyLocked(boolean locked) { this.isOnlyLocked = locked; } protected final String toIndexAddress(String index_dir) { char[] chars = index_dir.toCharArray(); StringBuilder sbr = new StringBuilder(pDirPath); sbr.append(LSystem.FS); sbr.append(chars[0]); sbr.append(chars[1]); sbr.append(LSystem.FS); sbr.append(chars[2]); sbr.append(LSystem.FS); sbr.append(pIndexName); return sbr.toString(); } public boolean findAddress(String key) throws IOException { return findAddress(toIndexAddress(key.toLowerCase()), key); } protected boolean findAddress(String hashPath, String key) throws IOException { File file = new File(hashPath); if (!file.exists()) { return false; } InputStream in = new BufferedInputStream(new FileInputStream(file)); boolean flag = findStream(key.getBytes(), in); in.close(); return flag; } public boolean findBlockAddress(String key) throws IOException { return findBlockAddress(toIndexAddress(key.toLowerCase()), key); } protected boolean findBlockAddress(String hashPath, String key) throws IOException { File file = new File(hashPath); if (!file.exists()) { return false; } byte[] buffers = AddressIndexBlock.findBlock(file, key); if (buffers == null || buffers.length == 0) { return false; } return NativeSupport.findCoinAddress(key.getBytes(), buffers); } private static boolean findStream(byte[] dst, InputStream is) throws IOException { int patternOffset = 0; int len = dst.length; int b = is.read(); for (; b != -1;) { if (dst[patternOffset] == ((byte) b)) { patternOffset++; if (patternOffset == len) { return true; } } else { patternOffset = 0; } b = is.read(); } return false; } protected boolean putAddress(String hashPath, String key) { if (isOnlyLocked) { try { if (findAddress(hashPath, key)) { return false; } } catch (IOException e) { e.printStackTrace(); } } synchronized (pPutAddress) { try { if (pPutAddress.size() > pMaxCache) { submit(); } FileWriter out = pPutAddress.get(hashPath); if (out == null) { File file = new File(hashPath); if (!file.exists()) { FileUtils.makedirs(file); } out = new FileWriter(hashPath, true); pPutAddress.put(hashPath, out); } out.write(key); out.write(LSystem.LS); } catch (Exception ex) { return false; } return true; } } public boolean putAddress(String key) { return putAddress(toIndexAddress(key.toLowerCase()), key); } public void submit() throws IOException { for (FileWriter out : pPutAddress.values()) { out.flush(); out.close(); } pPutAddress.clear(); } }