📄 sstrecord.java
字号:
public void setNumUniqueStrings( final int count ) { field_2_num_unique_strings = count; } /** * Get a particular string by its index * * @param id index into the array of strings * * @return the desired string */ public String getString( final int id ) { return ( (UnicodeString) field_3_strings.get( new Integer( id ) ) ).getString(); } public boolean isString16bit( final int id ) { UnicodeString unicodeString = ( (UnicodeString) field_3_strings.get( new Integer( id ) ) ); return ( ( unicodeString.getOptionFlags() & 0x01 ) == 1 ); } /** * Return a debugging string representation * * @return string representation */ public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append( "[SST]\n" ); buffer.append( " .numstrings = " ) .append( Integer.toHexString( getNumStrings() ) ).append( "\n" ); buffer.append( " .uniquestrings = " ) .append( Integer.toHexString( getNumUniqueStrings() ) ).append( "\n" ); for ( int k = 0; k < field_3_strings.size(); k++ ) { buffer.append( " .string_" + k + " = " ) .append( ( field_3_strings .get( new Integer( k ) ) ).toString() ).append( "\n" ); } buffer.append( "[/SST]\n" ); return buffer.toString(); } /** * @return sid */ public short getSid() { return sid; } /** * @return hashcode */ public int hashCode() { return field_2_num_unique_strings; } public boolean equals( Object o ) { if ( ( o == null ) || ( o.getClass() != this.getClass() ) ) { return false; } SSTRecord other = (SSTRecord) o; return ( ( field_1_num_strings == other .field_1_num_strings ) && ( field_2_num_unique_strings == other .field_2_num_unique_strings ) && field_3_strings .equals( other.field_3_strings ) ); } /** * validate SID * * @param id the alleged SID * * @exception RecordFormatException if validation fails */ protected void validateSid( final short id ) throws RecordFormatException { if ( id != sid ) { throw new RecordFormatException( "NOT An SST RECORD" ); } } /** * Fill the fields from the data * <P> * The data consists of sets of string data. This string data is * arranged as follows: * <P> * <CODE><pre> * short string_length; // length of string data * byte string_flag; // flag specifying special string * // handling * short run_count; // optional count of formatting runs * int extend_length; // optional extension length * char[] string_data; // string data, can be byte[] or * // short[] (length of array is * // string_length) * int[] formatting_runs; // optional formatting runs (length of * // array is run_count) * byte[] extension; // optional extension (length of array * // is extend_length) * </pre></CODE> * <P> * The string_flag is bit mapped as follows: * <P> * <TABLE> * <TR> * <TH>Bit number</TH> * <TH>Meaning if 0</TH> * <TH>Meaning if 1</TH> * <TR> * <TR> * <TD>0</TD> * <TD>string_data is byte[]</TD> * <TD>string_data is short[]</TH> * <TR> * <TR> * <TD>1</TD> * <TD>Should always be 0</TD> * <TD>string_flag is defective</TH> * <TR> * <TR> * <TD>2</TD> * <TD>extension is not included</TD> * <TD>extension is included</TH> * <TR> * <TR> * <TD>3</TD> * <TD>formatting run data is not included</TD> * <TD>formatting run data is included</TH> * <TR> * <TR> * <TD>4</TD> * <TD>Should always be 0</TD> * <TD>string_flag is defective</TH> * <TR> * <TR> * <TD>5</TD> * <TD>Should always be 0</TD> * <TD>string_flag is defective</TH> * <TR> * <TR> * <TD>6</TD> * <TD>Should always be 0</TD> * <TD>string_flag is defective</TH> * <TR> * <TR> * <TD>7</TD> * <TD>Should always be 0</TD> * <TD>string_flag is defective</TH> * <TR> * </TABLE> * <P> * We can handle eating the overhead associated with bits 2 or 3 * (or both) being set, but we have no idea what to do with the * associated data. The UnicodeString class can handle the byte[] * vs short[] nature of the actual string data * * @param data raw data * @param size size of the raw data */ protected void fillFields( final byte[] data, final short size, int offset ) { // this method is ALWAYS called after construction -- using // the nontrivial constructor, of course -- so this is where // we initialize our fields field_1_num_strings = LittleEndian.getInt( data, 0 + offset ); field_2_num_unique_strings = LittleEndian.getInt( data, 4 + offset ); field_3_strings = new BinaryTree(); deserializer = new SSTDeserializer(field_3_strings); deserializer.manufactureStrings( data, 8 + offset); } /** * @return an iterator of the strings we hold. All instances are * UnicodeStrings */ Iterator getStrings() { return field_3_strings.values().iterator(); } /** * @return count of the strings we hold. */ int countStrings() { return field_3_strings.size(); } /** * called by the class that is responsible for writing this sucker. * Subclasses should implement this so that their data is passed back in a * byte array. * * @return size */ public int serialize( int offset, byte[] data ) { SSTSerializer serializer = new SSTSerializer( _record_lengths, field_3_strings, getNumStrings(), getNumUniqueStrings() ); int bytes = serializer.serialize( getRecordSize(), offset, data ); bucketAbsoluteOffsets = serializer.getBucketAbsoluteOffsets(); bucketRelativeOffsets = serializer.getBucketRelativeOffsets();// for ( int i = 0; i < bucketAbsoluteOffsets.length; i++ )// {// System.out.println( "bucketAbsoluteOffset = " + bucketAbsoluteOffsets[i] );// System.out.println( "bucketRelativeOffset = " + bucketRelativeOffsets[i] );// } return bytes; } public int getRecordSize() { SSTRecordSizeCalculator calculator = new SSTRecordSizeCalculator(field_3_strings); int recordSize = calculator.getRecordSize(); _record_lengths = calculator.getRecordLengths(); return recordSize; } SSTDeserializer getDeserializer() { return deserializer; } /** * Strange to handle continue records this way. Is it a smell? */ public void processContinueRecord( byte[] record ) { deserializer.processContinueRecord( record ); } /** * Creates an extended string record based on the current contents of * the current SST record. The offset within the stream to the SST record * is required because the extended string record points directly to the * strings in the SST record. * <p> * NOTE: THIS FUNCTION MUST ONLY BE CALLED AFTER THE SST RECORD HAS BEEN * SERIALIZED. * * @param sstOffset The offset in the stream to the start of the * SST record. * @return The new SST record. */ public ExtSSTRecord createExtSSTRecord(int sstOffset) { if (bucketAbsoluteOffsets == null || bucketAbsoluteOffsets == null) throw new IllegalStateException("SST record has not yet been serialized."); ExtSSTRecord extSST = new ExtSSTRecord(); extSST.setNumStringsPerBucket((short)8); int[] absoluteOffsets = (int[]) bucketAbsoluteOffsets.clone(); int[] relativeOffsets = (int[]) bucketRelativeOffsets.clone(); for ( int i = 0; i < absoluteOffsets.length; i++ ) absoluteOffsets[i] += sstOffset; extSST.setBucketOffsets(absoluteOffsets, relativeOffsets); return extSST; } /** * Calculates the size in bytes of the EXTSST record as it would be if the * record was serialized. * * @return The size of the ExtSST record in bytes. */ public int calcExtSSTRecordSize() { return ExtSSTRecord.getRecordSizeForStrings(field_3_strings.size()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -