package org.ripple.power.database; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import org.ripple.power.config.LSystem; public class AddressIndexBlock { protected File pDataBaseFile; protected final int MAXLENGTH = 1 << 20; protected HashMap<String, String> pDict = new HashMap<String, String>(); public AddressIndexBlock(String path) { this(new File(path)); } public AddressIndexBlock(File path) { this.pDataBaseFile = path; } public File getFile() { return this.pDataBaseFile; } private void checkValid() { if (pDataBaseFile == null) { throw new RuntimeException("DataBase pointer was null"); } } private static byte[] output(HashMap<String, ArrayList<String>> keys) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(8192); DataOutputStream db = new DataOutputStream(out); for (String name : keys.keySet()) { byte[] key = name.getBytes(LSystem.encoding); StringBuilder sbr = new StringBuilder(); for (String val : keys.get(name)) { sbr.append(val); sbr.append("\n"); } byte[] value = sbr.toString().getBytes(LSystem.encoding); db.writeInt(key.length); db.writeInt(value.length); db.write(key); db.write(value); } byte[] bytes = out.toByteArray(); out.close(); return bytes; } protected static void putBlock(String tableFile, HashMap<String, HashMap<String, ArrayList<String>>> keys) throws IOException { try (DataOutputStream db = new DataOutputStream(new FileOutputStream( tableFile))) { for (String name : keys.keySet()) { byte[] key = name.getBytes(LSystem.encoding); ByteArrayOutputStream out = new ByteArrayOutputStream(8192); byte[] value = output(keys.get(name)); out.close(); db.writeInt(key.length); db.writeInt(value.length); db.write(key); db.write(value); } } catch (IOException e) { throw new IOException(String.format( "Conformity saving: IOException: %s", e.getMessage())); } } private static byte[] input(byte[] ins, String name) throws IOException { int find = Character.toLowerCase(name.charAt(4)); ByteArrayInputStream tmp = new ByteArrayInputStream(ins); DataInputStream in = new DataInputStream(tmp); for (;;) { in.readInt(); int valueLength = in.readInt(); byte keyBuffer = in.readByte(); if (keyBuffer == find) { byte[] valueBuffer = new byte[valueLength]; in.read(valueBuffer, 0, valueLength); return valueBuffer; } else { in.skipBytes(valueLength); } } } protected static byte[] findBlock(byte[] ins, String name) throws IOException { DataInputStream db = new DataInputStream(new ByteArrayInputStream(ins)); int find = Character.toLowerCase(name.charAt(3)); for (;;) { db.readInt(); int valueLength = db.readInt(); byte keyBuffer = db.readByte(); if (keyBuffer == find) { byte[] valueBuffer = new byte[valueLength]; db.read(valueBuffer, 0, valueLength); return input(valueBuffer, name); } else { db.skipBytes(valueLength); } } } protected static byte[] findBlock(String tableFile, String name) throws IOException { try (DataInputStream db = new DataInputStream(new FileInputStream( tableFile))) { int find = Character.toLowerCase(name.charAt(3)); for (;;) { db.readInt(); int valueLength = db.readInt(); byte keyBuffer = db.readByte(); if (keyBuffer == find) { byte[] valueBuffer = new byte[valueLength]; db.read(valueBuffer, 0, valueLength); return input(valueBuffer, name); } else { db.skipBytes(valueLength); } } } catch (Exception e) { return null; } } protected static byte[] findBlock(File tableFile, String name) throws IOException { try (DataInputStream db = new DataInputStream(new FileInputStream( tableFile))) { int find = Character.toLowerCase(name.charAt(3)); for (;;) { db.readInt(); int valueLength = db.readInt(); byte keyBuffer = db.readByte(); if (keyBuffer == find) { byte[] valueBuffer = new byte[valueLength]; db.read(valueBuffer, 0, valueLength); return input(valueBuffer, name); } else { db.skipBytes(valueLength); } } } catch (Exception e) { return null; } } public void open() throws IOException { checkValid(); if (!pDataBaseFile.exists() || pDataBaseFile.length() == 0) { pDict = new HashMap<String, String>(); return; } try (DataInputStream db = new DataInputStream(new FileInputStream( pDataBaseFile))) { while (true) { int keyLength; try { keyLength = db.readInt(); } catch (EOFException e) { break; } if (keyLength <= 0 || keyLength > MAXLENGTH) { throw new Exception(String.format( "Key length must be in [1; %d]", MAXLENGTH)); } int valueLength = db.readInt(); if (valueLength <= 0 || valueLength > MAXLENGTH) { throw new Exception(String.format( "Value length must be in [1; %d]", MAXLENGTH)); } byte[] keyBuffer = new byte[keyLength]; db.readFully(keyBuffer, 0, keyLength); String key = new String(keyBuffer, LSystem.encoding); byte[] valueBuffer = new byte[valueLength]; db.readFully(valueBuffer, 0, valueLength); String value = new String(valueBuffer, LSystem.encoding); pDict.put(key, value); } } catch (IOException e) { pDict = new HashMap<String, String>(); throw new IOException( String.format( "Conformity loading: IOException: %s. Empty database applied", e.getMessage())); } catch (Exception e) { pDict = new HashMap<String, String>(); throw new IOException( String.format( "Conformity loading: Exception: %s. Empty database applied", e.getMessage())); } } public void save() throws IOException { checkValid(); try (DataOutputStream db = new DataOutputStream(new FileOutputStream( pDataBaseFile))) { for (Map.Entry<String, String> entry : pDict.entrySet()) { byte[] key = entry.getKey().getBytes(LSystem.encoding); byte[] value = entry.getValue().getBytes(LSystem.encoding); db.writeInt(key.length); db.writeInt(value.length); db.write(key); db.write(value); } } catch (IOException e) { throw new IOException(String.format( "Conformity saving: IOException: %s", e.getMessage())); } } public String put(String key, String value) { return pDict.put(key, value); } public String remove(String key) { return pDict.remove(key); } public String get(String key) { return pDict.get(key); } protected String find(char c) { for (String name : pDict.keySet()) { if (name.indexOf(c) != -1) { return pDict.get(name); } } return null; } public static void main(String[] args) throws IOException { /* * AddressIndexBlock addressDataBase=new * AddressIndexBlock("d:\\tablettttttt.txt"); addressDataBase.open(); * addressDataBase.put("SSSSSSSSSSSS", "BBBBBBBBBBBBBBBBBBBBBBB"); * addressDataBase.save(); */ System.out.println(new String(AddressIndexBlock.findBlock( "d:\\tablettttttt.txt", "SSSSSSSSSSSS"))); } }