Author: frm
Date: Thu Aug 3 12:56:07 2017
New Revision: 1803995
URL: http://svn.apache.org/viewvc?rev=1803995&view=rev
Log:
OAK-6518 - Extract index load and validation logic in different class and
package
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/IndexLoader.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/InvalidIndexException.java
(with props)
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/TarReader.java
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/TarReader.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/TarReader.java?rev=1803995&r1=1803994&r2=1803995&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/TarReader.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/TarReader.java
Thu Aug 3 12:56:07 2017
@@ -33,7 +33,7 @@ import static org.apache.jackrabbit.oak.
import static
org.apache.jackrabbit.oak.segment.file.tar.TarConstants.BINARY_REFERENCES_MAGIC;
import static
org.apache.jackrabbit.oak.segment.file.tar.TarConstants.BLOCK_SIZE;
import static
org.apache.jackrabbit.oak.segment.file.tar.TarConstants.GRAPH_MAGIC;
-import static
org.apache.jackrabbit.oak.segment.file.tar.TarConstants.INDEX_MAGIC;
+import static
org.apache.jackrabbit.oak.segment.file.tar.index.IndexLoader.newIndexLoader;
import java.io.Closeable;
import java.io.File;
@@ -62,6 +62,8 @@ import com.google.common.base.Predicate;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Sets;
import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.oak.segment.file.tar.index.IndexLoader;
+import org.apache.jackrabbit.oak.segment.file.tar.index.InvalidIndexException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -69,6 +71,8 @@ class TarReader implements Closeable {
private static final Logger log = LoggerFactory.getLogger(TarReader.class);
+ private static final IndexLoader indexLoader = newIndexLoader(BLOCK_SIZE);
+
/**
* Pattern of the segment entry names. Note the trailing (\\..*)? group
* that's included for compatibility with possible future extensions.
@@ -335,79 +339,12 @@ class TarReader implements Closeable {
* instead.
*/
private static ByteBuffer loadAndValidateIndex(RandomAccessFile file,
String name) throws IOException {
- long length = file.length();
- if (length % BLOCK_SIZE != 0
- || length < 6 * BLOCK_SIZE
- || length > Integer.MAX_VALUE) {
- log.warn("Unexpected size {} of tar file {}", length, name);
- return null; // unexpected file size
- }
-
- // read the index metadata just before the two final zero blocks
- ByteBuffer meta = ByteBuffer.allocate(16);
- file.seek(length - 2 * BLOCK_SIZE - 16);
- file.readFully(meta.array());
- int crc32 = meta.getInt();
- int count = meta.getInt();
- int bytes = meta.getInt();
- int magic = meta.getInt();
-
- if (magic != INDEX_MAGIC) {
- return null; // magic byte mismatch
- }
-
- if (count < 1 || bytes < count * TarEntry.SIZE + 16 || bytes %
BLOCK_SIZE != 0) {
- log.warn("Invalid index metadata in tar file {}", name);
- return null; // impossible entry and/or byte counts
- }
-
- // this involves seeking backwards in the file, which might not
- // perform well, but that's OK since we only do this once per file
- ByteBuffer index = ByteBuffer.allocate(count * TarEntry.SIZE);
- file.seek(length - 2 * BLOCK_SIZE - 16 - count * TarEntry.SIZE);
- file.readFully(index.array());
- index.mark();
-
- CRC32 checksum = new CRC32();
- long limit = length - 2 * BLOCK_SIZE - bytes - BLOCK_SIZE;
- long lastmsb = Long.MIN_VALUE;
- long lastlsb = Long.MIN_VALUE;
- byte[] entry = new byte[TarEntry.SIZE];
- for (int i = 0; i < count; i++) {
- index.get(entry);
- checksum.update(entry);
-
- ByteBuffer buffer = wrap(entry);
- long msb = buffer.getLong();
- long lsb = buffer.getLong();
- int offset = buffer.getInt();
- int size = buffer.getInt();
-
- if (lastmsb > msb || (lastmsb == msb && lastlsb > lsb)) {
- log.warn("Incorrect index ordering in tar file {}", name);
- return null;
- } else if (lastmsb == msb && lastlsb == lsb && i > 0) {
- log.warn("Duplicate index entry in tar file {}", name);
- return null;
- } else if (offset < 0 || offset % BLOCK_SIZE != 0) {
- log.warn("Invalid index entry offset in tar file {}", name);
- return null;
- } else if (size < 1 || offset + size > limit) {
- log.warn("Invalid index entry size in tar file {}", name);
- return null;
- }
-
- lastmsb = msb;
- lastlsb = lsb;
- }
-
- if (crc32 != (int) checksum.getValue()) {
- log.warn("Invalid index checksum in tar file {}", name);
- return null; // checksum mismatch
+ try {
+ return indexLoader.loadIndex(file);
+ } catch (InvalidIndexException e) {
+ log.warn("Unable to load index of file {}: {}", name,
e.getMessage());
}
-
- index.reset();
- return index;
+ return null;
}
/**
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/IndexLoader.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/IndexLoader.java?rev=1803995&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/IndexLoader.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/IndexLoader.java
Thu Aug 3 12:56:07 2017
@@ -0,0 +1,116 @@
+/*
+ * 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.file.tar.index;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.nio.ByteBuffer.wrap;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.util.zip.CRC32;
+
+public class IndexLoader {
+
+ private static final int MAGIC = ('\n' << 24) + ('0' << 16) + ('K' << 8) +
'\n';
+
+ private static final int ENTRY_SIZE = 33;
+
+ public static IndexLoader newIndexLoader(int blockSize) {
+ checkArgument(blockSize > 0, "Invalid block size");
+ return new IndexLoader(blockSize);
+ }
+
+ private final int blockSize;
+
+ private IndexLoader(int blockSize) {
+ this.blockSize = blockSize;
+ }
+
+ public ByteBuffer loadIndex(RandomAccessFile file) throws IOException,
InvalidIndexException {
+ long length = file.length();
+
+ if (length % blockSize != 0 || length < 6 * blockSize || length >
Integer.MAX_VALUE) {
+ throw new InvalidIndexException(String.format("Unexpected size
%d", length));
+ }
+
+ // read the index metadata just before the two final zero blocks
+ ByteBuffer meta = ByteBuffer.allocate(16);
+ file.seek(length - 2 * blockSize - 16);
+ file.readFully(meta.array());
+ int crc32 = meta.getInt();
+ int count = meta.getInt();
+ int bytes = meta.getInt();
+ int magic = meta.getInt();
+
+ if (magic != MAGIC) {
+ return null; // magic byte mismatch
+ }
+
+ if (count < 1 || bytes < count * ENTRY_SIZE + 16 || bytes % blockSize
!= 0) {
+ throw new InvalidIndexException("Invalid metadata");
+ }
+
+ // this involves seeking backwards in the file, which might not
+ // perform well, but that's OK since we only do this once per file
+ ByteBuffer index = ByteBuffer.allocate(count * ENTRY_SIZE);
+ file.seek(length - 2 * blockSize - 16 - count * ENTRY_SIZE);
+ file.readFully(index.array());
+ index.mark();
+
+ CRC32 checksum = new CRC32();
+ long limit = length - 2 * blockSize - bytes - blockSize;
+ long lastMsb = Long.MIN_VALUE;
+ long lastLsb = Long.MIN_VALUE;
+ byte[] entry = new byte[ENTRY_SIZE];
+ for (int i = 0; i < count; i++) {
+ index.get(entry);
+ checksum.update(entry);
+
+ ByteBuffer buffer = wrap(entry);
+ long msb = buffer.getLong();
+ long lsb = buffer.getLong();
+ int offset = buffer.getInt();
+ int size = buffer.getInt();
+
+ if (lastMsb > msb || (lastMsb == msb && lastLsb > lsb)) {
+ throw new InvalidIndexException("Incorrect entry ordering");
+ }
+ if (lastMsb == msb && lastLsb == lsb && i > 0) {
+ throw new InvalidIndexException("Duplicate entry");
+ }
+ if (offset < 0 || offset % blockSize != 0) {
+ throw new InvalidIndexException("Invalid entry offset");
+ }
+ if (size < 1 || offset + size > limit) {
+ throw new InvalidIndexException("Invalid entry size");
+ }
+
+ lastMsb = msb;
+ lastLsb = lsb;
+ }
+
+ if (crc32 != (int) checksum.getValue()) {
+ throw new InvalidIndexException("Invalid checksum");
+ }
+
+ index.reset();
+ return index;
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/IndexLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/InvalidIndexException.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/InvalidIndexException.java?rev=1803995&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/InvalidIndexException.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/InvalidIndexException.java
Thu Aug 3 12:56:07 2017
@@ -0,0 +1,26 @@
+/*
+ * 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.file.tar.index;
+
+public class InvalidIndexException extends Exception {
+
+ InvalidIndexException(String message) {
+ super(message);
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/index/InvalidIndexException.java
------------------------------------------------------------------------------
svn:eol-style = native