Author: mduerig
Date: Mon Jul 20 15:33:59 2015
New Revision: 1691965
URL: http://svn.apache.org/r1691965
Log:
OAK-3123: NPE in RecordIdMap
* Properly guard against NPE
* Added test case for empty map
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordIdMap.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordIdMapTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordIdMap.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordIdMap.java?rev=1691965&r1=1691964&r2=1691965&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordIdMap.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordIdMap.java
Mon Jul 20 15:33:59 2015
@@ -29,8 +29,11 @@ import javax.annotation.Nonnull;
* A memory optimised map of {@code short} key to {@link RecordId} values.
*/
public class RecordIdMap {
- private short[] keys;
- private RecordId[] values;
+ private static final short[] NO_KEYS = new short[0];
+ private static final RecordId[] NO_VALUES = new RecordId[0];
+
+ private short[] keys = NO_KEYS;
+ private RecordId[] values = NO_VALUES;
/**
* Associates {@code key} with {@code value} if not already present
@@ -39,7 +42,7 @@ public class RecordIdMap {
* @return {@code true} if added, {@code false} if already present
*/
public boolean put(short key, @Nonnull RecordId value) {
- if (keys == null) {
+ if (keys.length == 0) {
keys = new short[1];
values = new RecordId[1];
keys[0] = key;
@@ -90,7 +93,7 @@ public class RecordIdMap {
* @return {@code true} iff {@code key} is present.
*/
public boolean containsKey(short key) {
- return keys != null && binarySearch(keys, key) >= 0;
+ return binarySearch(keys, key) >= 0;
}
/**
@@ -105,6 +108,7 @@ public class RecordIdMap {
* the natural ordering of shorts.
* @param index
* @return the key at {@code index}
+ * @throws ArrayIndexOutOfBoundsException if not {@code 0 <= index <
size()}
*/
public short getKey(int index) {
return keys[index];
@@ -115,6 +119,7 @@ public class RecordIdMap {
* the natural ordering of shorts.
* @param index
* @return the value at {@code index}
+ * @throws ArrayIndexOutOfBoundsException if not {@code 0 <= index <
size()}
*/
@Nonnull
public RecordId getRecordId(int index) {
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordIdMapTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordIdMapTest.java?rev=1691965&r1=1691964&r2=1691965&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordIdMapTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordIdMapTest.java
Mon Jul 20 15:33:59 2015
@@ -25,7 +25,10 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.plugins.segment.Segment.encode;
import static
org.apache.jackrabbit.oak.plugins.segment.TestUtils.newValidOffset;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.util.Map;
import java.util.Map.Entry;
@@ -37,6 +40,22 @@ import org.junit.Test;
public class RecordIdMapTest {
@Test
+ public void testEmpty() {
+ RecordIdMap map = new RecordIdMap();
+ assertFalse(map.containsKey((short) 0));
+ assertNull(map.get((short) 0));
+ assertEquals(0, map.size());
+ try {
+ map.getKey(0);
+ fail("Expected AIOBE");
+ } catch (ArrayIndexOutOfBoundsException ignored) {}
+ try {
+ map.getRecordId(0);
+ fail("Expected AIOBE");
+ } catch (ArrayIndexOutOfBoundsException ignored) {}
+ }
+
+ @Test
public void testRecordIdMap() {
int maxSegments = 1000;
int maxEntriesPerSegment = 10;