Index: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java =================================================================== --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java (revision 1839678) +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java (working copy) @@ -35,8 +35,7 @@ import java.io.IOException; import java.io.OutputStream; -import java.io.PrintWriter; -import java.io.StringWriter; +import java.io.PrintStream; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Iterator; @@ -46,7 +45,6 @@ import com.google.common.collect.AbstractIterator; import org.apache.commons.io.HexDump; import org.apache.commons.io.output.ByteArrayOutputStream; -import org.apache.commons.io.output.WriterOutputStream; import org.apache.jackrabbit.oak.api.PropertyState; import org.apache.jackrabbit.oak.api.Type; import org.apache.jackrabbit.oak.commons.StringUtils; @@ -547,34 +545,21 @@ @Override public String toString() { - StringWriter string = new StringWriter(); - try (PrintWriter writer = new PrintWriter(string)) { - writer.format("Segment %s (%d bytes)%n", id, data.size()); - String segmentInfo = getSegmentInfo(); - if (segmentInfo != null) { - writer.format("Info: %s, Generation: %s%n", segmentInfo, getGcGeneration()); - } - if (id.isDataSegmentId()) { - writer.println("--------------------------------------------------------------------------"); - int i = 1; - for (SegmentId segmentId : segmentReferences) { - writer.format("reference %02x: %s%n", i++, segmentId); - } - for (Entry entry : recordNumbers) { - int offset = entry.getOffset(); - writer.format("%10s record %08x: %08x @ %08x%n", - entry.getType(), entry.getRecordNumber(), offset, getAddress(offset)); + return SegmentDump.dumpSegment( + id, + data.size(), + info, + getGcGeneration(), + segmentReferences, + recordNumbers, + stream -> { + try { + data.hexDump(stream); + } catch (IOException e) { + e.printStackTrace(new PrintStream(stream)); } } - writer.println("--------------------------------------------------------------------------"); - try { - data.hexDump(new WriterOutputStream(writer, Charsets.UTF_8)); - } catch (IOException e) { - throw new IllegalStateException(e); - } - writer.println("--------------------------------------------------------------------------"); - } - return string.toString(); + ); } public void writeTo(OutputStream stream) throws IOException { Index: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriter.java =================================================================== --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriter.java (revision 1839678) +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentBufferWriter.java (working copy) @@ -30,6 +30,7 @@ import static org.apache.jackrabbit.oak.segment.Segment.GC_FULL_GENERATION_OFFSET; import static org.apache.jackrabbit.oak.segment.Segment.GC_GENERATION_OFFSET; import static org.apache.jackrabbit.oak.segment.Segment.HEADER_SIZE; +import static org.apache.jackrabbit.oak.segment.Segment.MAX_SEGMENT_SIZE; import static org.apache.jackrabbit.oak.segment.Segment.RECORD_ID_BYTES; import static org.apache.jackrabbit.oak.segment.Segment.RECORD_SIZE; import static org.apache.jackrabbit.oak.segment.Segment.SEGMENT_REFERENCE_SIZE; @@ -38,9 +39,11 @@ import static org.apache.jackrabbit.oak.segment.SegmentVersion.LATEST_VERSION; import java.io.IOException; +import java.io.PrintStream; import java.util.Collection; import java.util.Set; +import org.apache.commons.io.HexDump; import org.apache.jackrabbit.oak.segment.RecordNumbers.Entry; import org.apache.jackrabbit.oak.segment.file.tar.GCGeneration; import org.jetbrains.annotations.NotNull; @@ -175,7 +178,7 @@ * The segment meta data is guaranteed to be the first string record in a segment. */ private void newSegment(SegmentStore store) throws IOException { - buffer = new byte[Segment.MAX_SEGMENT_SIZE]; + buffer = new byte[MAX_SEGMENT_SIZE]; buffer[0] = '0'; buffer[1] = 'a'; buffer[2] = 'K'; @@ -283,6 +286,24 @@ dirty = true; } + private String dumpSegmentBuffer() { + return SegmentDump.dumpSegment( + segment != null ? segment.getSegmentId() : null, + length, + segment != null ? segment.getSegmentInfo() : null, + gcGeneration, + segmentReferences, + recordNumbers, + stream -> { + try { + HexDump.dump(buffer, 0, stream, 0); + } catch (IOException e) { + e.printStackTrace(new PrintStream(stream)); + } + } + ); + } + /** * Adds a segment header to the buffer and writes a segment to the segment * store. This is done automatically (called from prepare) when there is not @@ -302,6 +323,7 @@ int totalLength = align(HEADER_SIZE + referencedSegmentIdCount * SEGMENT_REFERENCE_SIZE + recordNumberCount * RECORD_SIZE + length, 16); if (totalLength > buffer.length) { + LOG.warn("Segment buffer corruption detected\n{}", dumpSegmentBuffer()); throw new IllegalStateException(String.format( "Too much data for a segment %s (referencedSegmentIdCount=%d, recordNumberCount=%d, length=%d, totalLength=%d)", segment.getSegmentId(), referencedSegmentIdCount, recordNumberCount, length, totalLength)); Index: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentDump.java =================================================================== --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentDump.java (nonexistent) +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentDump.java (working copy) @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.jackrabbit.oak.segment; + +import static org.apache.jackrabbit.oak.segment.Segment.MAX_SEGMENT_SIZE; + +import java.io.OutputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.function.Consumer; + +import com.google.common.base.Charsets; +import org.apache.commons.io.output.WriterOutputStream; +import org.apache.jackrabbit.oak.segment.RecordNumbers.Entry; +import org.apache.jackrabbit.oak.segment.file.tar.GCGeneration; + +class SegmentDump { + + private static int getAddress(int length, int offset) { + return length - (MAX_SEGMENT_SIZE - offset); + } + + static String dumpSegment(SegmentId id, int length, String segmentInfo, GCGeneration generation, SegmentReferences segmentReferences, RecordNumbers recordNumbers, Consumer dumper) { + StringWriter string = new StringWriter(); + try (PrintWriter writer = new PrintWriter(string)) { + writer.format("Segment %s (%d bytes)%n", id, length); + if (segmentInfo != null) { + writer.format("Info: %s, Generation: %s%n", segmentInfo, generation); + } + if (id != null && id.isDataSegmentId()) { + writer.println("--------------------------------------------------------------------------"); + int i = 1; + for (SegmentId segmentId : segmentReferences) { + writer.format("reference %02x: %s%n", i++, segmentId); + } + for (Entry entry : recordNumbers) { + int offset = entry.getOffset(); + writer.format("%10s record %08x: %08x @ %08x%n", + entry.getType(), entry.getRecordNumber(), offset, getAddress(length, offset)); + } + } + writer.println("--------------------------------------------------------------------------"); + dumper.accept(new WriterOutputStream(writer, Charsets.UTF_8)); + writer.println("--------------------------------------------------------------------------"); + } + return string.toString(); + } + +} Property changes on: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentDump.java ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property