You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2021/05/23 10:54:22 UTC
svn commit: r1890133 - in /pdfbox/trunk/pdfbox/src:
main/java/org/apache/pdfbox/cos/COSObjectKey.java
test/java/org/apache/pdfbox/cos/COSObjectKeyTest.java
Author: lehmi
Date: Sun May 23 10:54:22 2021
New Revision: 1890133
URL: http://svn.apache.org/viewvc?rev=1890133&view=rev
Log:
PDFBOX-5151: optimize internal representation of an object key based on a proposal by Roland Meub
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSObjectKey.java
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/COSObjectKeyTest.java
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSObjectKey.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSObjectKey.java?rev=1890133&r1=1890132&r2=1890133&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSObjectKey.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/cos/COSObjectKey.java Sun May 23 10:54:22 2021
@@ -22,10 +22,14 @@ package org.apache.pdfbox.cos;
* @author Michael Traut
*
*/
-public class COSObjectKey implements Comparable<COSObjectKey>
+public final class COSObjectKey implements Comparable<COSObjectKey>
{
- private final long number;
- private final int generation;
+ private static final int GENERATION_OFFSET = Long.SIZE - Short.SIZE;
+ private static final long NUMBER_MASK = (long) Math.pow(2, GENERATION_OFFSET) - 1;
+ // combined number and generation
+ // The highest 16 bits hold the generation 0-65535
+ // The rest is used for the number (even though 34 bit are sufficient for 10 digits)
+ private final long numberAndGeneration;
/**
* Constructor.
@@ -45,8 +49,15 @@ public class COSObjectKey implements Com
*/
public COSObjectKey(long num, int gen)
{
- number = num;
- generation = gen;
+ if (num < 0)
+ {
+ throw new IllegalArgumentException("Object number must not be a negative value");
+ }
+ if (gen < 0)
+ {
+ throw new IllegalArgumentException("Generation number must not be a negative value");
+ }
+ numberAndGeneration = (long) gen << GENERATION_OFFSET | (num & NUMBER_MASK);
}
/**
@@ -56,9 +67,8 @@ public class COSObjectKey implements Com
public boolean equals(Object obj)
{
COSObjectKey objToBeCompared = obj instanceof COSObjectKey ? (COSObjectKey)obj : null;
- return objToBeCompared != null &&
- objToBeCompared.getNumber() == getNumber() &&
- objToBeCompared.getGeneration() == getGeneration();
+ return objToBeCompared != null
+ && objToBeCompared.numberAndGeneration == numberAndGeneration;
}
/**
@@ -68,7 +78,7 @@ public class COSObjectKey implements Com
*/
public int getGeneration()
{
- return generation;
+ return (int) (numberAndGeneration >>> GENERATION_OFFSET);
}
/**
@@ -78,7 +88,7 @@ public class COSObjectKey implements Com
*/
public long getNumber()
{
- return number;
+ return numberAndGeneration & NUMBER_MASK;
}
/**
@@ -87,26 +97,19 @@ public class COSObjectKey implements Com
@Override
public int hashCode()
{
- // most likely generation is 0. Shift number 4 times (fast as multiply)
- // to support generation numbers up to 15
- return Long.valueOf((number << 4) + generation).hashCode();
+ return Long.hashCode(numberAndGeneration);
}
@Override
public String toString()
{
- return number + " " + generation + " R";
+ return Long.toString(getNumber()) + " " + Integer.toString(getGeneration()) + " R";
}
@Override
public int compareTo(COSObjectKey other)
{
- int result = Long.compare(getNumber(), other.getNumber());
- if (result == 0)
- {
- return Integer.compare(getGeneration(), other.getGeneration());
- }
- return result;
+ return Long.compare(numberAndGeneration, other.numberAndGeneration);
}
}
Modified: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/COSObjectKeyTest.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/COSObjectKeyTest.java?rev=1890133&r1=1890132&r2=1890133&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/COSObjectKeyTest.java (original)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/cos/COSObjectKeyTest.java Sun May 23 10:54:22 2021
@@ -17,18 +17,45 @@
package org.apache.pdfbox.cos;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import org.junit.jupiter.api.Test;
class COSObjectKeyTest
{
@Test
+ void testInputValues()
+ {
+ try
+ {
+ new COSObjectKey(-1L, 0);
+ fail("An IllegalArgumentException shouzld have been thrown");
+ }
+ catch (IllegalArgumentException exception)
+ {
+
+ }
+
+ try
+ {
+ new COSObjectKey(1L, -1);
+ fail("An IllegalArgumentException shouzld have been thrown");
+ }
+ catch (IllegalArgumentException exception)
+ {
+
+ }
+ }
+
+ @Test
void compareToInputNotNullOutputZero()
{
// Arrange
- final COSObjectKey objectUnderTest = new COSObjectKey(0L, 0);
- final COSObjectKey other = new COSObjectKey(0L, 0);
+ final COSObjectKey objectUnderTest = new COSObjectKey(1L, 0);
+ final COSObjectKey other = new COSObjectKey(1L, 0);
// Act
final int retval = objectUnderTest.compareTo(other);
@@ -38,17 +65,46 @@ class COSObjectKeyTest
}
@Test
- void compareToInputNotNullOutputPositive()
+ void compareToInputNotNullOutputNotNull()
{
// Arrange
- final COSObjectKey objectUnderTest = new COSObjectKey(0L, 0);
- final COSObjectKey other = new COSObjectKey(-9_223_372_036_854_775_808L, 0);
+ final COSObjectKey objectUnderTest = new COSObjectKey(1L, 0);
+ final COSObjectKey other = new COSObjectKey(9_999_999L, 0);
// Act
- final int retval = objectUnderTest.compareTo(other);
+ final int retvalNegative = objectUnderTest.compareTo(other);
+ final int retvalPositive = other.compareTo(objectUnderTest);
- // Assert result
- assertEquals(1, retval);
+ // Assert results
+ assertEquals(-1, retvalNegative);
+ assertEquals(1, retvalPositive);
+ }
+
+ @Test
+ void testEquals()
+ {
+ assertTrue(new COSObjectKey(100, 0).equals(new COSObjectKey(100, 0)));
+ assertFalse(new COSObjectKey(100, 0).equals(new COSObjectKey(101, 0)));
+ }
+
+ @Test
+ void testInternalRepresentation()
+ {
+ COSObjectKey key = new COSObjectKey(100, 0);
+ assertEquals(100, key.getNumber());
+ assertEquals(0, key.getGeneration());
+
+ key = new COSObjectKey(200, 4);
+ assertEquals(200, key.getNumber());
+ assertEquals(4, key.getGeneration());
+
+ key = new COSObjectKey(200000, 0);
+ assertEquals(200000, key.getNumber());
+ assertEquals(0, key.getGeneration());
+
+ key = new COSObjectKey(87654321, 123);
+ assertEquals(87654321, key.getNumber());
+ assertEquals(123, key.getGeneration());
}
@Test