@ -170,15 +170,13 @@ class PackIndexV2 extends PackIndex {
return offset64 . length / 8 ;
return offset64 . length / 8 ;
}
}
@Override
private int findLevelOne ( final long nthPosition ) {
public ObjectId getObjectId ( final long nthPosition ) {
int levelOne = Arrays . binarySearch ( fanoutTable , nthPosition + 1 ) ;
int levelOne = Arrays . binarySearch ( fanoutTable , nthPosition + 1 ) ;
long base ;
if ( levelOne > = 0 ) {
if ( levelOne > = 0 ) {
// If we hit the bucket exactly the item is in the bucket, or
// If we hit the bucket exactly the item is in the bucket, or
// any bucket before it which has the same object count.
// any bucket before it which has the same object count.
//
//
base = fanoutTable [ levelOne ] ;
long base = fanoutTable [ levelOne ] ;
while ( levelOne > 0 & & base = = fanoutTable [ levelOne - 1 ] )
while ( levelOne > 0 & & base = = fanoutTable [ levelOne - 1 ] )
levelOne - - ;
levelOne - - ;
} else {
} else {
@ -186,19 +184,39 @@ class PackIndexV2 extends PackIndex {
//
//
levelOne = - ( levelOne + 1 ) ;
levelOne = - ( levelOne + 1 ) ;
}
}
return levelOne ;
}
base = levelOne > 0 ? fanoutTable [ levelOne - 1 ] : 0 ;
private int getLevelTwo ( final long nthPosition , final int levelOne ) {
final int p = ( int ) ( nthPosition - base ) ;
final long base = levelOne > 0 ? fanoutTable [ levelOne - 1 ] : 0 ;
return ( int ) ( nthPosition - base ) ;
}
@Override
public ObjectId getObjectId ( final long nthPosition ) {
final int levelOne = findLevelOne ( nthPosition ) ;
final int p = getLevelTwo ( nthPosition , levelOne ) ;
final int p4 = p < < 2 ;
final int p4 = p < < 2 ;
return ObjectId . fromRaw ( names [ levelOne ] , p4 + p ) ; // p * 5
return ObjectId . fromRaw ( names [ levelOne ] , p4 + p ) ; // p * 5
}
}
@Override
public long getOffset ( final long nthPosition ) {
final int levelOne = findLevelOne ( nthPosition ) ;
final int levelTwo = getLevelTwo ( nthPosition , levelOne ) ;
return getOffset ( levelOne , levelTwo ) ;
}
@Override
@Override
public long findOffset ( final AnyObjectId objId ) {
public long findOffset ( final AnyObjectId objId ) {
final int levelOne = objId . getFirstByte ( ) ;
final int levelOne = objId . getFirstByte ( ) ;
final int levelTwo = binarySearchLevelTwo ( objId , levelOne ) ;
final int levelTwo = binarySearchLevelTwo ( objId , levelOne ) ;
if ( levelTwo = = - 1 )
if ( levelTwo = = - 1 )
return - 1 ;
return - 1 ;
return getOffset ( levelOne , levelTwo ) ;
}
private long getOffset ( final int levelOne , final int levelTwo ) {
final long p = NB . decodeUInt32 ( offset32 [ levelOne ] , levelTwo < < 2 ) ;
final long p = NB . decodeUInt32 ( offset32 [ levelOne ] , levelTwo < < 2 ) ;
if ( ( p & IS_O64 ) ! = 0 )
if ( ( p & IS_O64 ) ! = 0 )
return NB . decodeUInt64 ( offset64 , ( 8 * ( int ) ( p & ~ IS_O64 ) ) ) ;
return NB . decodeUInt64 ( offset64 , ( 8 * ( int ) ( p & ~ IS_O64 ) ) ) ;