package de.mxro.thrd.jdbm2V22.btree; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import de.mxro.thrd.jdbm2V22.helper.LongPacker; /** * Provider for implementations {@link ByteArrayCompressor}suitable for storing * binary data, {@link BinaryCompressionProvider}, or {@link String} data, * {@link StringCompressionProvider}. * * @author Kevin Day */ class LeadingValueCompressionProvider { /** * Read previously written data */ static byte[] readByteArray( DataInputStream in, byte[] previous, int ignoreLeadingCount ) throws IOException { int len = LongPacker.unpackInt(in) -1; if (len == -1) return null; int actualCommon = 0; actualCommon = LongPacker.unpackInt(in); byte[] buf = new byte[ len ]; if (previous == null){ actualCommon = 0; } if (actualCommon > 0){ in.readFully( buf, 0, ignoreLeadingCount); System.arraycopy(previous, ignoreLeadingCount, buf, ignoreLeadingCount, actualCommon - ignoreLeadingCount); } in.readFully( buf, actualCommon, len - actualCommon ); return buf; } /** * Writes the contents of buf to the DataOutput out, with special encoding if * there are common leading bytes in the previous group stored by this compressor. */ static void writeByteArray( DataOutputStream out, byte[] buf, byte[] previous, int ignoreLeadingCount ) throws IOException { if ( buf == null ) { LongPacker.packInt(out, 0); return; } int actualCommon = ignoreLeadingCount; if (previous != null){ int maxCommon = buf.length > previous.length ? previous.length : buf.length; if (maxCommon > Short.MAX_VALUE) maxCommon = Short.MAX_VALUE; for (; actualCommon < maxCommon; actualCommon++) { if (buf[actualCommon] != previous[actualCommon]) break; } } // there are enough common bytes to justify compression LongPacker.packInt(out,buf.length+1 );// store as +1, 0 indicates null LongPacker.packInt(out,actualCommon ); out.write( buf, 0, ignoreLeadingCount); out.write( buf, actualCommon, buf.length - actualCommon ); } // static String findCommonStringPrefix(Object[] strs) { // int commonChars = 1; // // String minimalString = null; // int minimalSize =Integer.MAX_VALUE; // //find first non null string and minimal size // for(Object s2:strs){ // String s = (String) s2; // if(s!=null && minimalSize>s.length()){ // minimalSize = s.length(); // minimalString = s; // } // } // //all null // if(minimalString == null) // return null; // // String previousPrefix = ""; // while(commonChars<=minimalSize){ // String prefix = minimalString.substring(0,commonChars); // //check if all strings stars with the same prefix // for(Object s2:strs){ // String s = (String) s2; // if(s!=null && !s.startsWith(prefix)){ // //does not start, return previous // return previousPrefix; // } // } // // //all ok, add one more common byte // previousPrefix = prefix; // commonChars++; // } // return previousPrefix; // // } }