signature:
public class Arrays { /** * Performs a binary search on an already sorted range : finds the last position where an element
 * can be inserted without violating the ordering . Sorting is by a user - supplied comparison
 * function .
 * @ param from the index of the first element ( inclusive ) to be included in the binary search .
 * @ param to the index of the last element ( exclusive ) to be included in the binary search .
 * @ param pos the position of the element to be searched for .
 * @ param comp the comparison function .
 * @ return The largest index i such that , for every j in the range { @ code [ first . . i ) } ,
 * { @ code comp . compare ( pos , j ) } is { @ code false } . */
private static int upperBound ( int from , final int mid , final int pos , final IntComparator comp ) { } }

implementation:
// if ( comp = = null ) throw new NullPointerException ( ) ;
int len = mid - from ; while ( len > 0 ) { int half = len / 2 ; int middle = from + half ; if ( comp . compare ( pos , middle ) < 0 ) { len = half ; } else { from = middle + 1 ; len -= half + 1 ; } } return from ;


signature:
public class Arrays { /** * Sorts the specified range of elements using the specified swapper and according to the order induced by the specified
 * comparator using mergesort .
 * < p > This sort is guaranteed to be < i > stable < / i > : equal elements will not be reordered as a result
 * of the sort . The sorting algorithm is an in - place mergesort that is significantly slower than a
 * standard mergesort , as its running time is < i > O < / i > ( < var > n < / var > & nbsp ; ( log & nbsp ; < var > n < / var > ) < sup > 2 < / sup > ) , but it does not allocate additional memory ; as a result , it can be
 * used as a generic sorting algorithm .
 * @ param from the index of the first element ( inclusive ) to be sorted .
 * @ param to the index of the last element ( exclusive ) to be sorted .
 * @ param c the comparator to determine the order of the generic data ( arguments are positions ) .
 * @ param swapper an object that knows how to swap the elements at any two positions . */
public static void mergeSort ( final int from , final int to , final IntComparator c , final Swapper swapper ) { } }

implementation:
/* * We retain the same method signature as quickSort . Given only a comparator and swapper we
 * do not know how to copy and move elements from / to temporary arrays . Hence , in contrast to
 * the JDK mergesorts this is an " in - place " mergesort , i . e . does not allocate any temporary
 * arrays . A non - inplace mergesort would perhaps be faster in most cases , but would require
 * non - intuitive delegate objects . . . */
final int length = to - from ; // Insertion sort on smallest arrays
if ( length < MERGESORT_NO_REC ) { for ( int i = from ; i < to ; i ++ ) { for ( int j = i ; j > from && ( c . compare ( j - 1 , j ) > 0 ) ; j -- ) { swapper . swap ( j , j - 1 ) ; } } return ; } // Recursively sort halves
int mid = ( from + to ) >>> 1 ; mergeSort ( from , mid , c , swapper ) ; mergeSort ( mid , to , c , swapper ) ; // If list is already sorted , nothing left to do . This is an
// optimization that results in faster sorts for nearly ordered lists .
if ( c . compare ( mid - 1 , mid ) <= 0 ) return ; // Merge sorted halves
inPlaceMerge ( from , mid , to , c , swapper ) ;


signature:
public class Arrays { /** * Swaps two sequences of elements using a provided swapper .
 * @ param swapper the swapper .
 * @ param a a position in { @ code x } .
 * @ param b another position in { @ code x } .
 * @ param n the number of elements to exchange starting at { @ code a } and { @ code b } . */
protected static void swap ( final Swapper swapper , int a , int b , final int n ) { } }

implementation: for ( int i = 0 ; i < n ; i ++ , a ++ , b ++ ) swapper . swap ( a , b ) ;


signature:
public class Arrays { /** * Sorts the specified range of elements using the specified swapper and according to the order induced by the specified
 * comparator using a parallel quicksort .
 * < p > The sorting algorithm is a tuned quicksort adapted from Jon L . Bentley and M . Douglas
 * McIlroy , & ldquo ; Engineering a Sort Function & rdquo ; , < i > Software : Practice and Experience < / i > , 23(11 ) , pages
 * 1249 & minus ; 1265 , 1993.
 * < p > This implementation uses a { @ link ForkJoinPool } executor service with { @ link Runtime # availableProcessors ( ) } parallel threads .
 * @ param from the index of the first element ( inclusive ) to be sorted .
 * @ param to the index of the last element ( exclusive ) to be sorted .
 * @ param comp the comparator to determine the order of the generic data .
 * @ param swapper an object that knows how to swap the elements at any two positions . */
public static void parallelQuickSort ( final int from , final int to , final IntComparator comp , final Swapper swapper ) { } }

implementation: final ForkJoinPool pool = new ForkJoinPool ( Runtime . getRuntime ( ) . availableProcessors ( ) ) ; pool . invoke ( new ForkJoinGenericQuickSort ( from , to , comp , swapper ) ) ; pool . shutdown ( ) ;


signature:
public class Arrays { /** * Sorts the specified range of elements using the specified swapper and according to the order induced by the specified
 * comparator using parallel quicksort .
 * < p > The sorting algorithm is a tuned quicksort adapted from Jon L . Bentley and M . Douglas
 * McIlroy , & ldquo ; Engineering a Sort Function & rdquo ; , < i > Software : Practice and Experience < / i > , 23(11 ) , pages
 * 1249 & minus ; 1265 , 1993.
 * < p > This implementation uses a { @ link ForkJoinPool } executor service with { @ link Runtime # availableProcessors ( ) } parallel threads .
 * @ param from the index of the first element ( inclusive ) to be sorted .
 * @ param to the index of the last element ( exclusive ) to be sorted .
 * @ param comp the comparator to determine the order of the generic data .
 * @ param swapper an object that knows how to swap the elements at any two positions . */
public static void quickSort ( final int from , final int to , final IntComparator comp , final Swapper swapper ) { } }

implementation:
final int len = to - from ; // Insertion sort on smallest arrays
if ( len < QUICKSORT_NO_REC ) { for ( int i = from ; i < to ; i ++ ) for ( int j = i ; j > from && ( comp . compare ( j - 1 , j ) > 0 ) ; j -- ) { swapper . swap ( j , j - 1 ) ; } return ; } // Choose a partition element , v
int m = from + len / 2 ; // Small arrays , middle element
int l = from ; int n = to - 1 ; if ( len > QUICKSORT_MEDIAN_OF_9 ) { // Big arrays , pseudomedian of 9
int s = len / 8 ; l = med3 ( l , l + s , l + 2 * s , comp ) ; m = med3 ( m - s , m , m + s , comp ) ; n = med3 ( n - 2 * s , n - s , n , comp ) ; } m = med3 ( l , m , n , comp ) ; // Mid - size , med of 3
// int v = x [ m ] ;
int a = from ; int b = a ; int c = to - 1 ; // Establish Invariant : v * ( < v ) * ( > v ) * v *
int d = c ; while ( true ) { int comparison ; while ( b <= c && ( ( comparison = comp . compare ( b , m ) ) <= 0 ) ) { if ( comparison == 0 ) { // Fix reference to pivot if necessary
if ( a == m ) m = b ; else if ( b == m ) m = a ; swapper . swap ( a ++ , b ) ; } b ++ ; } while ( c >= b && ( ( comparison = comp . compare ( c , m ) ) >= 0 ) ) { if ( comparison == 0 ) { // Fix reference to pivot if necessary
if ( c == m ) m = d ; else if ( d == m ) m = c ; swapper . swap ( c , d -- ) ; } c -- ; } if ( b > c ) break ; // Fix reference to pivot if necessary
if ( b == m ) m = d ; else if ( c == m ) m = c ; swapper . swap ( b ++ , c -- ) ; } // Swap partition elements back to middle
int s ; s = Math . min ( a - from , b - a ) ; swap ( swapper , from , b - s , s ) ; s = Math . min ( d - c , to - d - 1 ) ; swap ( swapper , b , to - s , s ) ; // Recursively sort non - partition - elements
if ( ( s = b - a ) > 1 ) quickSort ( from , from + s , comp , swapper ) ; if ( ( s = d - c ) > 1 ) quickSort ( to - s , to , comp , swapper ) ;


signature:
public class HashCommon { /** * Avalanches the bits of an integer by applying the finalisation step of MurmurHash3.
 * < p > This method implements the finalisation step of Austin Appleby ' s < a href = " http : / / code . google . com / p / smhasher / " > MurmurHash3 < / a > .
 * Its purpose is to avalanche the bits of the argument to within 0.25 % bias .
 * @ param x an integer .
 * @ return a hash value with good avalanching properties . */
public static int murmurHash3 ( int x ) { } }


signature:
public class HashCommon { /** * Avalanches the bits of a long integer by applying the finalisation step of MurmurHash3.
 * < p > This method implements the finalisation step of Austin Appleby ' s < a href = " http : / / code . google . com / p / smhasher / " > MurmurHash3 < / a > .
 * Its purpose is to avalanche the bits of the argument to within 0.25 % bias .
 * @ param x a long integer .
 * @ return a hash value with good avalanching properties . */
public static long murmurHash3 ( long x ) { } }


signature:
public class InspectableFileCachedInputStream { /** * Clears the content of this { @ link InspectableFileCachedInputStream } , zeroing the length of the represented
 * stream . */
public void clear ( ) throws IOException { } }

implementation: if ( ! fileChannel . isOpen ( ) ) throw new IOException ( "This " + getClass ( ) . getSimpleName ( ) + " is closed" ) ; writePosition = position = inspectable = 0 ; mark = - 1 ;


signature:
public class InspectableFileCachedInputStream { /** * Appends the content of a specified buffer to the end of the currently represented stream .
 * @ param byteBuffer a byte buffer .
 * @ return the number of bytes appended ( i . e . , { @ link ByteBuffer # remaining ( ) byteBuffer . remaining ( ) } ) . */
@ Override public int write ( final ByteBuffer byteBuffer ) throws IOException { } }

implementation:
ensureOpen ( ) ; final int remaining = byteBuffer . remaining ( ) ; if ( inspectable < buffer . length ) { // Still some space in the inspectable buffer .
final int toBuffer = Math . min ( buffer . length - inspectable , remaining ) ; byteBuffer . get ( buffer , inspectable , toBuffer ) ; inspectable += toBuffer ; } if ( byteBuffer . hasRemaining ( ) ) { fileChannel . position ( writePosition ) ; writePosition += fileChannel . write ( byteBuffer ) ; } return remaining ;


signature:
public class InspectableFileCachedInputStream { /** * Truncates the overflow file to a given size if possible .
 * @ param size the new size ; the final size is the maximum between the current write position ( i . e . , the length
 * of the represented stream minus the length of the inspection buffer ) and this value . */
public void truncate ( final long size ) throws FileNotFoundException , IOException { } }

implementation: fileChannel . truncate ( Math . max ( size , writePosition ) ) ;


signature:
public class FastByteArrayInputStream { /** * Reads bytes from this byte - array input stream as
 * specified in { @ link java . io . InputStream # read ( byte [ ] , int , int ) } .
 * Note that the implementation given in { @ link java . io . ByteArrayInputStream # read ( byte [ ] , int , int ) }
 * will return - 1 on a zero - length read at EOF , contrarily to the specification . We won ' t . */
@ Override public int read ( final byte b [ ] , final int offset , final int length ) { } }

implementation: if ( this . length == this . position ) return length == 0 ? 0 : - 1 ; final int n = Math . min ( length , this . length - this . position ) ; System . arraycopy ( array , this . offset + this . position , b , offset , n ) ; this . position += n ; return n ;


signature:
public class FastBufferedOutputStream { /** * Repositions the stream .
 * < p > Note that this method performs a { @ link # flush ( ) } before changing the underlying stream position . */
@ Override public void position ( final long newPosition ) throws IOException { } }

implementation: flush ( ) ; if ( repositionableStream != null ) repositionableStream . position ( newPosition ) ; else if ( fileChannel != null ) fileChannel . position ( newPosition ) ; else throw new UnsupportedOperationException ( "position() can only be called if the underlying byte stream implements the RepositionableStream interface or if the getChannel() method of the underlying byte stream exists and returns a FileChannel" ) ;


signature:
public class AbstractRefreshMetricsListener { /** * This method acquires details of individual transitions that comprise a larger refresh .
 * Details of transitions in a refresh such as count and type can be useful to understand consumer performance and
 * to troubleshoot issues relating to refresh failure .
 * @ param beforeVersion The version when refresh started
 * @ param desiredVersion The version that the consumer refresh tries update to , even though it might not be attainable eg . HollowConstants . VERSION _ LATEST
 * @ param isSnapshotPlan Indicates whether the refresh involves a snapshot transition
 * @ param transitionSequence List of transitions comprising the refresh */
@ Override public final void transitionsPlanned ( long beforeVersion , long desiredVersion , boolean isSnapshotPlan , List < HollowConsumer . Blob . BlobType > transitionSequence ) { } }

implementation: updatePlanDetails . beforeVersion = beforeVersion ; updatePlanDetails . desiredVersion = desiredVersion ; updatePlanDetails . transitionSequence = transitionSequence ; if ( isSnapshotPlan ) { overallRefreshType = BlobType . SNAPSHOT ; } else { overallRefreshType = desiredVersion > beforeVersion ? BlobType . DELTA : BlobType . REVERSE_DELTA ; } refreshMetricsBuilder . setOverallRefreshType ( overallRefreshType ) ;


signature:
public class AbstractRefreshMetricsListener { /** * Metrics reporting implementation is provided by the extending subclass . If exceptions are not gracefully handled
 * in the extending subclass then an exception there can fail the consumer refresh , even though metrics reporting
 * might not be mission critical . This method protects against that scenario by catching all exceptions , logging
 * that there was an exception , and continuing with the consumer refresh .
 * @ param refreshMetrics Consumer refresh metrics being reported */
private final void noFailRefreshEndMetricsReporting ( ConsumerRefreshMetrics refreshMetrics ) { } }

implementation:
try { refreshEndMetricsReporting ( refreshMetrics ) ; } catch ( Exception e ) { // Metric reporting is not considered critical to consumer refresh . Log exceptions and continue .
log . log ( Level . SEVERE , "Encountered an exception in reporting consumer refresh metrics, ignoring exception and continuing with consumer refresh" , e ) ; }


signature:
public class SimultaneousExecutor { /** * Await successful completion of all previously submitted tasks . Throw exception of the first failed task
 * if 1 or more tasks failed .
 * After this call completes , the thread pool will < i > not < / i > be shut down and can be reused .
 * @ throws ExecutionException if a computation threw an
 * exception
 * @ throws InterruptedException if the current thread was interrupted
 * while waiting */
public void awaitSuccessfulCompletionOfCurrentTasks ( ) throws InterruptedException , ExecutionException { } }

implementation: for ( Future < ? > f : futures ) { f . get ( ) ; } futures . clear ( ) ;


signature:
public class HashIndex { /** * Starts the building of a { @ link HashIndex } .
 * @ param consumer the consumer containing instances of the given root type
 * @ param rootType the root type to match and select from
 * @ param < T > the root type
 * @ return a builder */
public static < T extends HollowRecord > Builder < T > from ( HollowConsumer consumer , Class < T > rootType ) { } }

implementation: Objects . requireNonNull ( consumer ) ; Objects . requireNonNull ( rootType ) ; return new Builder < > ( consumer , rootType ) ;


signature:
public class HashIndexSelect { /** * Finds matches for a given query .
 * @ param query the query
 * @ return a stream of matching records ( may be empty if there are no matches ) */
public Stream < S > findMatches ( Q query ) { } }

implementation: Object [ ] queryArray = matchFields . stream ( ) . map ( mf -> mf . extract ( query ) ) . toArray ( ) ; HollowHashIndexResult matches = hhi . findMatches ( queryArray ) ; if ( matches == null ) { return Stream . empty ( ) ; } return matches . stream ( ) . mapToObj ( i -> selectField . extract ( api , i ) ) ;


signature:
public class HollowCompactor { /** * Perform a compaction . It is expected that :
 * < ul >
 * < li > the { @ link HollowWriteStateEngine } supplied in the constructor is unmodified since the
 * last call to { @ link HollowWriteStateEngine # prepareForNextCycle ( ) } < / li >
 * < li > the { @ link HollowReadStateEngine } supplied in the constructor reflects the same state as
 * the HollowWriteStateEngine . < / li >
 * < / ul > */
public void compact ( ) { } }

implementation:
Set < String > compactionTargets = findCompactionTargets ( ) ; Map < String , BitSet > relocatedOrdinals = new HashMap < String , BitSet > ( ) ; PartialOrdinalRemapper remapper = new PartialOrdinalRemapper ( ) ; for ( String compactionTarget : compactionTargets ) { HollowTypeReadState typeState = readEngine . getTypeState ( compactionTarget ) ; HollowTypeWriteState writeState = writeEngine . getTypeState ( compactionTarget ) ; BitSet populatedOrdinals = typeState . getListener ( PopulatedOrdinalListener . class ) . getPopulatedOrdinals ( ) ; BitSet typeRelocatedOrdinals = new BitSet ( populatedOrdinals . length ( ) ) ; int populatedCardinality = populatedOrdinals . cardinality ( ) ; writeState . addAllObjectsFromPreviousCycle ( ) ; int numRelocations = 0 ; int ordinalToRelocate = populatedOrdinals . nextSetBit ( populatedCardinality ) ; while ( ordinalToRelocate != - 1 ) { numRelocations ++ ; ordinalToRelocate = populatedOrdinals . nextSetBit ( ordinalToRelocate + 1 ) ; } HollowRecordCopier copier = HollowRecordCopier . createCopier ( typeState ) ; IntMap remappedOrdinals = new IntMap ( numRelocations ) ; ordinalToRelocate = populatedOrdinals . length ( ) ; int relocatePosition = - 1 ; try { for ( int i = 0 ; i < numRelocations ; i ++ ) { while ( ! populatedOrdinals . get ( -- ordinalToRelocate ) ) ; relocatePosition = populatedOrdinals . nextClearBit ( relocatePosition + 1 ) ; typeRelocatedOrdinals . set ( ordinalToRelocate ) ; writeState . removeOrdinalFromThisCycle ( ordinalToRelocate ) ; HollowWriteRecord rec = copier . copy ( ordinalToRelocate ) ; writeState . mapOrdinal ( rec , relocatePosition , false , true ) ; remappedOrdinals . put ( ordinalToRelocate , relocatePosition ) ; } } finally { writeState . recalculateFreeOrdinals ( ) ; } remapper . addOrdinalRemapping ( compactionTarget , remappedOrdinals ) ; relocatedOrdinals . put ( compactionTarget , typeRelocatedOrdinals ) ; } // / find the referencing dependents
TransitiveSetTraverser . addReferencingOutsideClosure ( readEngine , relocatedOrdinals ) ; // / copy all forward except remapped and transitive dependents of remapped
for ( HollowSchema schema : HollowSchemaSorter . dependencyOrderedSchemaList ( writeEngine . getSchemas ( ) ) ) { if ( ! compactionTargets . contains ( schema . getName ( ) ) ) { HollowTypeWriteState writeState = writeEngine . getTypeState ( schema . getName ( ) ) ; writeState . addAllObjectsFromPreviousCycle ( ) ; BitSet typeRelocatedOrdinals = relocatedOrdinals . get ( schema . getName ( ) ) ; if ( typeRelocatedOrdinals != null ) { HollowTypeReadState readState = readEngine . getTypeState ( schema . getName ( ) ) ; IntMap remappedOrdinals = new IntMap ( typeRelocatedOrdinals . cardinality ( ) ) ; boolean preserveHashPositions = shouldPreserveHashPositions ( schema ) ; HollowRecordCopier copier = HollowRecordCopier . createCopier ( readState , remapper , preserveHashPositions ) ; int remapOrdinal = typeRelocatedOrdinals . nextSetBit ( 0 ) ; while ( remapOrdinal != - 1 ) { HollowWriteRecord rec = copier . copy ( remapOrdinal ) ; int newOrdinal = writeState . add ( rec ) ; remappedOrdinals . put ( remapOrdinal , newOrdinal ) ; writeState . removeOrdinalFromThisCycle ( remapOrdinal ) ; remapOrdinal = typeRelocatedOrdinals . nextSetBit ( remapOrdinal + 1 ) ; } remapper . addOrdinalRemapping ( schema . getName ( ) , remappedOrdinals ) ; } } }


signature:
public class HollowCompactor { /** * Find candidate types for compaction . No two types in the returned set will have a dependency relationship , either
 * directly or transitively . */
private Set < String > findCompactionTargets ( ) { } }

implementation: List < HollowSchema > schemas = HollowSchemaSorter . dependencyOrderedSchemaList ( readEngine . getSchemas ( ) ) ; Set < String > typesToCompact = new HashSet < String > ( ) ; for ( HollowSchema schema : schemas ) { if ( isCompactionCandidate ( schema . getName ( ) ) ) { if ( ! candidateIsDependentOnAnyTargetedType ( schema . getName ( ) , typesToCompact ) ) typesToCompact . add ( schema . getName ( ) ) ; } } return typesToCompact ;


signature:
public class HollowPrimaryKeyIndex { /** * Query an index with a single specified field . The returned value with be the ordinal of the matching record .
 * Use a generated API or the Generic Object API to use the returned ordinal .
 * @ param key the field key
 * @ return the matching ordinal for the key , otherwise - 1 if the key is not present */
public int getMatchingOrdinal ( Object key ) { } }

implementation: PrimaryKeyIndexHashTable hashTable = hashTableVolatile ; if ( fieldPathIndexes . length != 1 || hashTable . bitsPerElement == 0 ) return - 1 ; int hashCode = keyHashCode ( key , 0 ) ; int ordinal = - 1 ; do { hashTable = this . hashTableVolatile ; int bucket = hashCode & hashTable . hashMask ; ordinal = readOrdinal ( hashTable , bucket ) ; while ( ordinal != - 1 ) { if ( keyDeriver . keyMatches ( key , ordinal , 0 ) ) break ; bucket ++ ; bucket &= hashTable . hashMask ; ordinal = readOrdinal ( hashTable , bucket ) ; } } while ( hashTableVolatile != hashTable ) ; return ordinal ;


signature:
public class HollowPrimaryKeyIndex { /** * Query an index with four or more specified fields . The returned value with be the ordinal of the matching record .
 * Use a generated API or the Generic Object API to use the returned ordinal .
 * @ param keys the field keys
 * @ return the matching ordinal for the keys , otherwise - 1 if the key is not present */
public int getMatchingOrdinal ( Object ... keys ) { } }

implementation: PrimaryKeyIndexHashTable hashTable = hashTableVolatile ; if ( fieldPathIndexes . length != keys . length || hashTable . bitsPerElement == 0 ) return - 1 ; int hashCode = 0 ; for ( int i = 0 ; i < keys . length ; i ++ ) hashCode ^= keyHashCode ( keys [ i ] , i ) ; int ordinal = - 1 ; do { hashTable = this . hashTableVolatile ; int bucket = hashCode & hashTable . hashMask ; ordinal = readOrdinal ( hashTable , bucket ) ; while ( ordinal != - 1 ) { if ( keyDeriver . keyMatches ( ordinal , keys ) ) break ; bucket ++ ; bucket &= hashTable . hashMask ; ordinal = readOrdinal ( hashTable , bucket ) ; } } while ( hashTableVolatile != hashTable ) ; return ordinal ;


signature:
public class SegmentedLongArray { /** * Set the byte at the given index to the specified value
 * @ param index the index
 * @ param value the byte value */
public void set ( long index , long value ) { } }

implementation:
int segmentIndex = ( int ) ( index >> log2OfSegmentSize ) ; int longInSegment = ( int ) ( index & bitmask ) ; unsafe . putOrderedLong ( segments [ segmentIndex ] , ( long ) Unsafe . ARRAY_LONG_BASE_OFFSET + ( 8 * longInSegment ) , value ) ; // / duplicate the longs here so that we can read faster .
if ( longInSegment == 0 && segmentIndex != 0 ) unsafe . putOrderedLong ( segments [ segmentIndex - 1 ] , ( long ) Unsafe . ARRAY_LONG_BASE_OFFSET + ( 8 * ( 1 << log2OfSegmentSize ) ) , value ) ;


signature:
public class HollowFilesystemBlobStorageCleaner { /** * Cleans snapshot to keep the last ' n ' snapshots . Defaults to 5. */
@ Override public void cleanSnapshots ( ) { } }

implementation: File [ ] files = getFilesByType ( HollowProducer . Blob . Type . SNAPSHOT . prefix ) ; if ( files == null || files . length <= numOfSnapshotsToKeep ) { return ; } sortByLastModified ( files ) ; for ( int i = numOfSnapshotsToKeep ; i < files . length ; i ++ ) { File file = files [ i ] ; boolean deleted = file . delete ( ) ; if ( ! deleted ) { log . warning ( "Could not delete snapshot " + file . getPath ( ) ) ; } }


signature:
public class HollowReadFieldUtils { /** * Hash a field in an OBJECT record .
 * @ param typeAccess the data access
 * @ param ordinal the ordinal
 * @ param fieldPosition the field position
 * @ return the hash code */
public static int fieldHashCode ( HollowObjectTypeDataAccess typeAccess , int ordinal , int fieldPosition ) { } }

implementation: HollowObjectSchema schema = typeAccess . getSchema ( ) ; switch ( schema . getFieldType ( fieldPosition ) ) { case BOOLEAN : Boolean bool = typeAccess . readBoolean ( ordinal , fieldPosition ) ; return booleanHashCode ( bool ) ; case BYTES : case STRING : return typeAccess . findVarLengthFieldHashCode ( ordinal , fieldPosition ) ; case DOUBLE : double d = typeAccess . readDouble ( ordinal , fieldPosition ) ; return doubleHashCode ( d ) ; case FLOAT : float f = typeAccess . readFloat ( ordinal , fieldPosition ) ; return floatHashCode ( f ) ; case INT : return intHashCode ( typeAccess . readInt ( ordinal , fieldPosition ) ) ; case LONG : long l = typeAccess . readLong ( ordinal , fieldPosition ) ; return longHashCode ( l ) ; case REFERENCE : return typeAccess . readOrdinal ( ordinal , fieldPosition ) ; } throw new IllegalStateException ( "I don't know how to hash a " + schema . getFieldType ( fieldPosition ) ) ;


signature:
public class HollowReadFieldUtils { /** * Determine whether two OBJECT field records are exactly equal .
 * @ param typeAccess1 the first type access
 * @ param ordinal1 the first ordinal
 * @ param fieldPosition1 the first field positiom
 * @ param typeAccess2 the second type access
 * @ param ordinal2 the second ordinal
 * @ param fieldPosition2 the second field position
 * @ return if the two OBJECT field records are exactly equal */
public static boolean fieldsAreEqual ( HollowObjectTypeDataAccess typeAccess1 , int ordinal1 , int fieldPosition1 , HollowObjectTypeDataAccess typeAccess2 , int ordinal2 , int fieldPosition2 ) { } }

implementation: HollowObjectSchema schema1 = typeAccess1 . getSchema ( ) ; switch ( schema1 . getFieldType ( fieldPosition1 ) ) { case BOOLEAN : Boolean bool1 = typeAccess1 . readBoolean ( ordinal1 , fieldPosition1 ) ; Boolean bool2 = typeAccess2 . readBoolean ( ordinal2 , fieldPosition2 ) ; return bool1 == bool2 ; case BYTES : byte [ ] data1 = typeAccess1 . readBytes ( ordinal1 , fieldPosition1 ) ; byte [ ] data2 = typeAccess2 . readBytes ( ordinal2 , fieldPosition2 ) ; return Arrays . equals ( data1 , data2 ) ; case DOUBLE : double d1 = typeAccess1 . readDouble ( ordinal1 , fieldPosition1 ) ; double d2 = typeAccess2 . readDouble ( ordinal2 , fieldPosition2 ) ; return Double . compare ( d1 , d2 ) == 0 ; case FLOAT : float f1 = typeAccess1 . readFloat ( ordinal1 , fieldPosition1 ) ; float f2 = typeAccess2 . readFloat ( ordinal2 , fieldPosition2 ) ; return Float . compare ( f1 , f2 ) == 0 ; case INT : int i1 = typeAccess1 . readInt ( ordinal1 , fieldPosition1 ) ; int i2 = typeAccess2 . readInt ( ordinal2 , fieldPosition2 ) ; return i1 == i2 ; case LONG : long l1 = typeAccess1 . readLong ( ordinal1 , fieldPosition1 ) ; long l2 = typeAccess2 . readLong ( ordinal2 , fieldPosition2 ) ; return l1 == l2 ; case STRING : String s1 = typeAccess1 . readString ( ordinal1 , fieldPosition1 ) ; return typeAccess2 . isStringFieldEqual ( ordinal2 , fieldPosition2 , s1 ) ; case REFERENCE : if ( typeAccess1 == typeAccess2 && fieldPosition1 == fieldPosition2 ) return typeAccess1 . readOrdinal ( ordinal1 , fieldPosition1 ) == typeAccess2 . readOrdinal ( ordinal2 , fieldPosition2 ) ; default : } throw new IllegalStateException ( "I don't know how to test equality for a " + schema1 . getFieldType ( fieldPosition1 ) ) ;


signature:
public class TransitiveSetTraverser { /** * Augment the given selection by adding the references , and the < i > transitive < / i > references , of our selection .
 * @ param stateEngine the state engine
 * @ param matches the map to which matches are placed */
public static void addTransitiveMatches ( HollowReadStateEngine stateEngine , Map < String , BitSet > matches ) { } }

implementation: List < HollowSchema > schemaList = HollowSchemaSorter . dependencyOrderedSchemaList ( stateEngine ) ; Collections . reverse ( schemaList ) ; for ( HollowSchema schema : schemaList ) { BitSet currentMatches = matches . get ( schema . getName ( ) ) ; if ( currentMatches != null ) { addTransitiveMatches ( stateEngine , schema . getName ( ) , matches ) ; } }


signature:
public class TransitiveSetTraverser { /** * Remove any records from the given selection which are referenced by other records not in the selection .
 * @ param stateEngine the state engine
 * @ param matches the matches */
public static void removeReferencedOutsideClosure ( HollowReadStateEngine stateEngine , Map < String , BitSet > matches ) { } }

implementation: List < HollowSchema > orderedSchemas = HollowSchemaSorter . dependencyOrderedSchemaList ( stateEngine ) ; Collections . reverse ( orderedSchemas ) ; for ( HollowSchema referencedSchema : orderedSchemas ) { if ( matches . containsKey ( referencedSchema . getName ( ) ) ) { for ( HollowSchema referencerSchema : orderedSchemas ) { if ( referencerSchema == referencedSchema ) break ; if ( matches . containsKey ( referencedSchema . getName ( ) ) && matches . get ( referencedSchema . getName ( ) ) . cardinality ( ) > 0 ) traverseReferencesOutsideClosure ( stateEngine , referencerSchema . getName ( ) , referencedSchema . getName ( ) , matches , REMOVE_REFERENCED_OUTSIDE_CLOSURE ) ; } } }


signature:
public class TransitiveSetTraverser { /** * Augment the given selection with any records outside the selection which reference
 * ( or transitively reference ) any records in the selection .
 * @ param stateEngine the state engine
 * @ param matches the matches */
public static void addReferencingOutsideClosure ( HollowReadStateEngine stateEngine , Map < String , BitSet > matches ) { } }

implementation: List < HollowSchema > orderedSchemas = HollowSchemaSorter . dependencyOrderedSchemaList ( stateEngine ) ; for ( HollowSchema referencerSchema : orderedSchemas ) { for ( HollowSchema referencedSchema : orderedSchemas ) { if ( referencedSchema == referencerSchema ) break ; if ( matches . containsKey ( referencedSchema . getName ( ) ) && matches . get ( referencedSchema . getName ( ) ) . cardinality ( ) > 0 ) traverseReferencesOutsideClosure ( stateEngine , referencerSchema . getName ( ) , referencedSchema . getName ( ) , matches , ADD_REFERENCING_OUTSIDE_CLOSURE ) ; } }


signature:
public class HollowClientUpdater { /** * Note that this method is synchronized and it is the only method that modifies the
 * { @ code hollowDataHolderVolatile } , so we don ' t need to worry about it changing out from
 * under us . */
public synchronized boolean updateTo ( long requestedVersion ) throws Throwable { } }

implementation:
if ( requestedVersion == getCurrentVersionId ( ) ) { if ( requestedVersion == HollowConstants . VERSION_NONE && hollowDataHolderVolatile == null ) { LOG . warning ( "No versions to update to, initializing to empty state" ) ; // attempting to refresh , but no available versions - initialize to empty state
hollowDataHolderVolatile = newHollowDataHolder ( ) ; forceDoubleSnapshotNextUpdate ( ) ; // intentionally ignore doubleSnapshotConfig
} return true ; } // Take a snapshot of the listeners to ensure additions or removals may occur concurrently
// but will not take effect until a subsequent refresh
final HollowConsumer . RefreshListener [ ] localListeners = refreshListeners . toArray ( new HollowConsumer . RefreshListener [ 0 ] ) ; long beforeVersion = getCurrentVersionId ( ) ; for ( HollowConsumer . RefreshListener listener : localListeners ) listener . refreshStarted ( beforeVersion , requestedVersion ) ; try { HollowUpdatePlan updatePlan = shouldCreateSnapshotPlan ( ) ? planner . planInitializingUpdate ( requestedVersion ) : planner . planUpdate ( hollowDataHolderVolatile . getCurrentVersion ( ) , requestedVersion , doubleSnapshotConfig . allowDoubleSnapshot ( ) ) ; for ( HollowConsumer . RefreshListener listener : localListeners ) if ( listener instanceof HollowConsumer . TransitionAwareRefreshListener ) ( ( HollowConsumer . TransitionAwareRefreshListener ) listener ) . transitionsPlanned ( beforeVersion , requestedVersion , updatePlan . isSnapshotPlan ( ) , updatePlan . getTransitionSequence ( ) ) ; if ( updatePlan . destinationVersion ( ) == HollowConstants . VERSION_NONE && requestedVersion != HollowConstants . VERSION_LATEST ) throw new IllegalArgumentException ( String . format ( "Could not create an update plan for version %s, because that version or any previous versions could not be retrieved." , requestedVersion ) ) ; if ( updatePlan . equals ( HollowUpdatePlan . DO_NOTHING ) && requestedVersion == HollowConstants . VERSION_LATEST ) throw new IllegalArgumentException ( "Could not create an update plan, because no existing versions could be retrieved." ) ; if ( updatePlan . destinationVersion ( requestedVersion ) == getCurrentVersionId ( ) ) return true ; if ( updatePlan . isSnapshotPlan ( ) ) { if ( hollowDataHolderVolatile == null || doubleSnapshotConfig . allowDoubleSnapshot ( ) ) { hollowDataHolderVolatile = newHollowDataHolder ( ) ; hollowDataHolderVolatile . update ( updatePlan , localListeners ) ; forceDoubleSnapshot = false ; } } else { hollowDataHolderVolatile . update ( updatePlan , localListeners ) ; } for ( HollowConsumer . RefreshListener refreshListener : localListeners ) refreshListener . refreshSuccessful ( beforeVersion , getCurrentVersionId ( ) , requestedVersion ) ; metrics . updateTypeStateMetrics ( getStateEngine ( ) , requestedVersion ) ; if ( metricsCollector != null ) metricsCollector . collect ( metrics ) ; initialLoad . complete ( getCurrentVersionId ( ) ) ; // only set the first time
return getCurrentVersionId ( ) == requestedVersion ; } catch ( Throwable th ) { forceDoubleSnapshotNextUpdate ( ) ; metrics . updateRefreshFailed ( ) ; if ( metricsCollector != null ) metricsCollector . collect ( metrics ) ; for ( HollowConsumer . RefreshListener refreshListener : localListeners ) refreshListener . refreshFailed ( beforeVersion , getCurrentVersionId ( ) , requestedVersion , th ) ; // intentionally omitting a call to initialLoad . completeExceptionally ( th ) , for producers
// that write often a consumer has a chance to try another snapshot that might succeed
throw th ; }


signature:
public class AbstractProducerMetricsListener { /** * Reports metrics for when cycle is skipped due to reasons such as the producer not being the leader in a multiple - producer setting .
 * In a multiple producer setting , leader election typically favors long - lived leaders to avoid producer runs from frequently requiring
 * to reload the full state before publishing data . When a cycle is skipped because the producer wasn ' t primary , the current value of
 * no . of consecutive failures and most recent cycle success time are retained , and no cycle status ( success or fail ) is reported .
 * @ param reason Reason why the run was skipped */
@ Override public void onCycleSkip ( CycleSkipReason reason ) { } }

implementation:
cycleMetricsBuilder . setConsecutiveFailures ( consecutiveFailures ) ; lastCycleSuccessTimeNanoOptional . ifPresent ( cycleMetricsBuilder :: setLastCycleSuccessTimeNano ) ; // isCycleSuccess and cycleDurationMillis are not set for skipped cycles
cycleMetricsBuilder . setConsecutiveFailures ( consecutiveFailures ) ; cycleMetricsReporting ( cycleMetricsBuilder . build ( ) ) ;


signature:
public class AbstractProducerMetricsListener { /** * Reports announcement - related metrics .
 * @ param status Indicates whether the announcement succeeded of failed
 * @ param readState Hollow data state that is being published , used in this method for computing data size
 * @ param version Version of data that was announced
 * @ param elapsed Announcement start to end duration */
@ Override public void onAnnouncementComplete ( com . netflix . hollow . api . producer . Status status , HollowProducer . ReadState readState , long version , Duration elapsed ) { } }

implementation: boolean isAnnouncementSuccess = false ; long dataSizeBytes = 0l ; if ( status . getType ( ) == com . netflix . hollow . api . producer . Status . StatusType . SUCCESS ) { isAnnouncementSuccess = true ; lastAnnouncementSuccessTimeNanoOptional = OptionalLong . of ( System . nanoTime ( ) ) ; } HollowReadStateEngine stateEngine = readState . getStateEngine ( ) ; dataSizeBytes = stateEngine . calcApproxDataSize ( ) ; announcementMetricsBuilder . setDataSizeBytes ( dataSizeBytes ) . setIsAnnouncementSuccess ( isAnnouncementSuccess ) . setAnnouncementDurationMillis ( elapsed . toMillis ( ) ) ; lastAnnouncementSuccessTimeNanoOptional . ifPresent ( announcementMetricsBuilder :: setLastAnnouncementSuccessTimeNano ) ; announcementMetricsReporting ( announcementMetricsBuilder . build ( ) ) ;


signature:
public class AbstractProducerMetricsListener { /** * On cycle completion this method reports cycle metrics .
 * @ param status Whether the cycle succeeded or failed
 * @ param readState Hollow data state published by cycle , not used here because data size is known from when announcement completed
 * @ param version Version of data that was published in this cycle
 * @ param elapsed Cycle start to end duration */
@ Override public void onCycleComplete ( com . netflix . hollow . api . producer . Status status , HollowProducer . ReadState readState , long version , Duration elapsed ) { } }

implementation: boolean isCycleSuccess ; long cycleEndTimeNano = System . nanoTime ( ) ; if ( status . getType ( ) == com . netflix . hollow . api . producer . Status . StatusType . SUCCESS ) { isCycleSuccess = true ; consecutiveFailures = 0l ; lastCycleSuccessTimeNanoOptional = OptionalLong . of ( cycleEndTimeNano ) ; } else { isCycleSuccess = false ; consecutiveFailures ++ ; } cycleMetricsBuilder . setConsecutiveFailures ( consecutiveFailures ) . setCycleDurationMillis ( elapsed . toMillis ( ) ) . setIsCycleSuccess ( isCycleSuccess ) ; lastCycleSuccessTimeNanoOptional . ifPresent ( cycleMetricsBuilder :: setLastCycleSuccessTimeNano ) ; cycleMetricsReporting ( cycleMetricsBuilder . build ( ) ) ;


signature:
public class HollowBlobHeaderReader { /** * Map of string header tags reading .
 * @ param dis
 * @ throws IOException */
private Map < String , String > readHeaderTags ( DataInputStream dis ) throws IOException { } }

implementation: int numHeaderTags = dis . readShort ( ) ; Map < String , String > headerTags = new HashMap < String , String > ( ) ; for ( int i = 0 ; i < numHeaderTags ; i ++ ) { headerTags . put ( dis . readUTF ( ) , dis . readUTF ( ) ) ; } return headerTags ;


signature:
public class HollowObjectMapper { /** * Adds the specified POJO to the state engine .
 * Unless previously initialized with { @ link # initializeTypeState ( Class ) } ,
 * the first time an instance of a particular type is added
 * its schema is derived and added to the data model .
 * @ param o the POJO to add
 * @ return the ordinal assigned to the newly added object */
public int add ( Object o ) { } }

implementation: HollowTypeMapper typeMapper = getTypeMapper ( o . getClass ( ) , null , null ) ; return typeMapper . write ( o ) ;


signature:
public class HollowObjectMapper { /** * Warning : Experimental . the FlatRecord feature is subject to breaking changes . */
@ Deprecated public void writeFlat ( Object o , FlatRecordWriter flatRecordWriter ) { } }

implementation: HollowTypeMapper typeMapper = getTypeMapper ( o . getClass ( ) , null , null ) ; typeMapper . writeFlat ( o , flatRecordWriter ) ;


signature:
public class HollowObjectMapper { /** * Extracts the primary key from the specified POJO .
 * @ param o the POJO
 * @ return the primary key
 * @ throws IllegalArgumentException if the POJO does not have primary key defined */
public RecordPrimaryKey extractPrimaryKey ( Object o ) { } }

implementation: HollowObjectTypeMapper typeMapper = ( HollowObjectTypeMapper ) getTypeMapper ( o . getClass ( ) , null , null ) ; return new RecordPrimaryKey ( typeMapper . getTypeName ( ) , typeMapper . extractPrimaryKey ( o ) ) ;


signature:
public class HollowObjectMapper { /** * Initializes the schema for the specified type in the data model .
 * The schema will be derived from the field and type names in
 * < code > clazz < / code > and added to the state engine ' s data model ;
 * schemas of types referenced from < code > clazz < / code > will also be added .
 * This can be used to add a type ' s schema to the state engine
 * without having to add any data for that type .
 * @ param clazz type whose schema to derive and add to the data model
 * @ see # add ( Object ) */
public void initializeTypeState ( Class < ? > clazz ) { } }

implementation: Objects . requireNonNull ( clazz ) ; getTypeMapper ( clazz , null , null ) ;


signature:
public class ThreadSafeBitSet { /** * Clear all bits to 0. */
public void clearAll ( ) { } }

implementation: ThreadSafeBitSetSegments segments = this . segments . get ( ) ; for ( int i = 0 ; i < segments . numSegments ( ) ; i ++ ) { AtomicLongArray segment = segments . getSegment ( i ) ; for ( int j = 0 ; j < segment . length ( ) ; j ++ ) { segment . set ( j , 0L ) ; } }


signature:
public class ThreadSafeBitSet { /** * Return a new bit set which contains all bits which are contained in this bit set , and which are NOT contained in the < code > other < / code > bit set . < p >
 * In other words , return a new bit set , which is a bitwise and with the bitwise not of the other bit set .
 * @ param other the other bit set
 * @ return the resulting bit set */
public ThreadSafeBitSet andNot ( ThreadSafeBitSet other ) { } }

implementation: if ( other . log2SegmentSize != log2SegmentSize ) throw new IllegalArgumentException ( "Segment sizes must be the same" ) ; ThreadSafeBitSetSegments thisSegments = this . segments . get ( ) ; ThreadSafeBitSetSegments otherSegments = other . segments . get ( ) ; ThreadSafeBitSetSegments newSegments = new ThreadSafeBitSetSegments ( thisSegments . numSegments ( ) , numLongsPerSegment ) ; for ( int i = 0 ; i < thisSegments . numSegments ( ) ; i ++ ) { AtomicLongArray thisArray = thisSegments . getSegment ( i ) ; AtomicLongArray otherArray = ( i < otherSegments . numSegments ( ) ) ? otherSegments . getSegment ( i ) : null ; AtomicLongArray newArray = newSegments . getSegment ( i ) ; for ( int j = 0 ; j < thisArray . length ( ) ; j ++ ) { long thisLong = thisArray . get ( j ) ; long otherLong = ( otherArray == null ) ? 0 : otherArray . get ( j ) ; newArray . set ( j , thisLong & ~ otherLong ) ; } } ThreadSafeBitSet andNot = new ThreadSafeBitSet ( log2SegmentSize ) ; andNot . segments . set ( newSegments ) ; return andNot ;


signature:
public class ThreadSafeBitSet { /** * Return a new bit set which contains all bits which are contained in * any * of the specified bit sets .
 * @ param bitSets the other bit sets
 * @ return the resulting bit set */
public static ThreadSafeBitSet orAll ( ThreadSafeBitSet ... bitSets ) { } }

implementation: if ( bitSets . length == 0 ) return new ThreadSafeBitSet ( ) ; int log2SegmentSize = bitSets [ 0 ] . log2SegmentSize ; int numLongsPerSegment = bitSets [ 0 ] . numLongsPerSegment ; ThreadSafeBitSetSegments segments [ ] = new ThreadSafeBitSetSegments [ bitSets . length ] ; int maxNumSegments = 0 ; for ( int i = 0 ; i < bitSets . length ; i ++ ) { if ( bitSets [ i ] . log2SegmentSize != log2SegmentSize ) throw new IllegalArgumentException ( "Segment sizes must be the same" ) ; segments [ i ] = bitSets [ i ] . segments . get ( ) ; if ( segments [ i ] . numSegments ( ) > maxNumSegments ) maxNumSegments = segments [ i ] . numSegments ( ) ; } ThreadSafeBitSetSegments newSegments = new ThreadSafeBitSetSegments ( maxNumSegments , numLongsPerSegment ) ; AtomicLongArray segment [ ] = new AtomicLongArray [ segments . length ] ; for ( int i = 0 ; i < maxNumSegments ; i ++ ) { for ( int j = 0 ; j < segments . length ; j ++ ) { segment [ j ] = i < segments [ j ] . numSegments ( ) ? segments [ j ] . getSegment ( i ) : null ; } AtomicLongArray newSegment = newSegments . getSegment ( i ) ; for ( int j = 0 ; j < numLongsPerSegment ; j ++ ) { long value = 0 ; for ( int k = 0 ; k < segments . length ; k ++ ) { if ( segment [ k ] != null ) value |= segment [ k ] . get ( j ) ; } newSegment . set ( j , value ) ; } } ThreadSafeBitSet or = new ThreadSafeBitSet ( log2SegmentSize ) ; or . segments . set ( newSegments ) ; return or ;


signature:
public class ThreadSafeBitSet { /** * Get the segment at < code > segmentIndex < / code > . If this segment does not yet exist , create it .
 * @ param segmentIndex the segment index
 * @ return the segment */
private AtomicLongArray getSegment ( int segmentIndex ) { } }

implementation:
ThreadSafeBitSetSegments visibleSegments = segments . get ( ) ; while ( visibleSegments . numSegments ( ) <= segmentIndex ) { // / Thread safety : newVisibleSegments contains all of the segments from the currently visible segments , plus extra .
// / all of the segments in the currently visible segments are canonical and will not change .
ThreadSafeBitSetSegments newVisibleSegments = new ThreadSafeBitSetSegments ( visibleSegments , segmentIndex + 1 , numLongsPerSegment ) ; // / because we are using a compareAndSet , if this thread " wins the race " and successfully sets this variable , then the segments
// / which are newly defined in newVisibleSegments become canonical .
if ( segments . compareAndSet ( visibleSegments , newVisibleSegments ) ) { visibleSegments = newVisibleSegments ; } else { // / If we " lose the race " and are growing the ThreadSafeBitSet segments larger ,
// / then we will gather the new canonical sets from the update which we missed on the next iteration of this loop .
// / Newly defined segments in newVisibleSegments will be discarded , they do not get to become canonical .
visibleSegments = segments . get ( ) ; } } return visibleSegments . getSegment ( segmentIndex ) ;


signature:
public class HollowProducerMetrics { /** * Updates the producer metrics :
 * cycles completed , version and type ' s footprint and ordinals .
 * @ param producerStatus the producer status */
public void updateCycleMetrics ( HollowProducerListener . ProducerStatus producerStatus ) { } }

implementation: Status . StatusType st = producerStatus . getStatus ( ) == HollowProducerListener . Status . SUCCESS ? Status . StatusType . SUCCESS : Status . StatusType . FAIL ; updateCycleMetrics ( new Status ( st , producerStatus . getCause ( ) ) , producerStatus . getReadState ( ) , producerStatus . getVersion ( ) ) ;


signature:
public class HollowProducerMetrics { /** * Updates the producer metrics :
 * cycles completed , version and type ' s footprint and ordinals .
 * @ param status the status
 * @ param readState the read state
 * @ param version the version */
public void updateCycleMetrics ( Status status , HollowProducer . ReadState readState , long version ) { } }

implementation: cyclesCompleted ++ ; if ( status . getType ( ) == Status . StatusType . FAIL ) { cycleFailed ++ ; return ; } cyclesSucceeded ++ ; if ( readState != null ) { HollowReadStateEngine hollowReadStateEngine = readState . getStateEngine ( ) ; super . update ( hollowReadStateEngine , version ) ; } else { super . update ( version ) ; }


signature:
public class HollowPOJOGenerator { /** * Usage : java HollowPOJOGenerator - - argName1 = argValue1 - - argName2 = = argValue2 . See { @ link GeneratorArguments }
 * for available arguments .
 * @ param args the arguments
 * @ throws IOException if the POJOs cannot be created
 * @ throws ClassNotFoundException if the class for a data type cannot be loaded */
public static void main ( String [ ] args ) throws IOException , ClassNotFoundException { } }

implementation: if ( args . length == 0 ) { System . out . println ( "Usage:\n" + "java " + HollowPOJOGenerator . class . getName ( ) + " --arg1=value1 --arg2=value2\n" + "see " + GeneratorArguments . class . getName ( ) + " for available arguments." ) ; return ; } HollowWriteStateEngine engine = new HollowWriteStateEngine ( ) ; String packageName = null ; String pojoClassNameSuffix = null ; String pathToGeneratedFiles = null ; HollowObjectMapper mapper = new HollowObjectMapper ( engine ) ; ArgumentParser < GeneratorArguments > argumentParser = new ArgumentParser ( GeneratorArguments . class , args ) ; for ( ArgumentParser < GeneratorArguments > . ParsedArgument arg : argumentParser . getParsedArguments ( ) ) { switch ( arg . getKey ( ) ) { case addToDataModel : mapper . initializeTypeState ( HollowPOJOGenerator . class . getClassLoader ( ) . loadClass ( arg . getValue ( ) ) ) ; break ; case addSchemaFileToDataModel : HollowWriteStateCreator . readSchemaFileIntoWriteState ( arg . getValue ( ) , engine ) ; break ; case pathToGeneratedFiles : pathToGeneratedFiles = arg . getValue ( ) ; break ; case packageName : packageName = arg . getValue ( ) ; break ; case pojoClassNameSuffix : pojoClassNameSuffix = arg . getValue ( ) ; break ; default : throw new IllegalArgumentException ( "Unhandled argument " + arg . getKey ( ) ) ; } } new HollowPOJOGenerator ( packageName , pojoClassNameSuffix , engine ) . generateFiles ( pathToGeneratedFiles ) ;


signature:
public class SnapshotPopulatedOrdinalsReader { /** * Read populated ordinals as a bit set from a stream , and notify a listener for each populated ordinal .
 * @ param dis the data input stream
 * @ param listeners the type state listeners
 * @ throws IOException if the ordinals cannot be read
 * @ author dkoszewnik */
public static void readOrdinals ( DataInputStream dis , HollowTypeStateListener [ ] listeners ) throws IOException { } }

implementation: int numLongs = dis . readInt ( ) ; int currentOrdinal = 0 ; for ( int i = 0 ; i < numLongs ; i ++ ) { long l = dis . readLong ( ) ; notifyPopulatedOrdinals ( l , currentOrdinal , listeners ) ; currentOrdinal += 64 ; }


signature:
public class HollowSparseIntegerSet { /** * Check if the given value is contained in the set ( or if the given value satisfies the predicate condition . )
 * @ param i the integer value
 * @ return { @ code true } if the value is present */
public boolean get ( int i ) { } }

implementation: SparseBitSet current ; boolean result ; do { current = sparseBitSetVolatile ; result = current . get ( i ) ; } while ( current != sparseBitSetVolatile ) ; return result ;


signature:
public class HollowSparseIntegerSet { /** * Estimate the total number of bits used to represent the integer set .
 * @ return Calculates the total number of bits used by longs in underlying data structure . */
public long size ( ) { } }

implementation: SparseBitSet current ; long size ; do { current = sparseBitSetVolatile ; size = current . estimateBitsUsed ( ) ; } while ( current != sparseBitSetVolatile ) ; return size ;


signature:
public class HollowBlobReader { /** * Initialize the state engine using a snapshot blob from the provided InputStream .
 * Apply the provided { @ link HollowFilterConfig } to the state .
 * @ param is the input stream to read the snaptshot
 * @ param filter the filtering configuration to filter the snapshot
 * @ throws IOException if the snapshot could not be read */
public void readSnapshot ( InputStream is , HollowFilterConfig filter ) throws IOException { } }

implementation: HollowBlobHeader header = readHeader ( is , false ) ; notifyBeginUpdate ( ) ; long startTime = System . currentTimeMillis ( ) ; DataInputStream dis = new DataInputStream ( is ) ; int numStates = VarInt . readVInt ( dis ) ; Collection < String > typeNames = new TreeSet < String > ( ) ; for ( int i = 0 ; i < numStates ; i ++ ) { String typeName = readTypeStateSnapshot ( dis , header , filter ) ; typeNames . add ( typeName ) ; } stateEngine . wireTypeStatesToSchemas ( ) ; long endTime = System . currentTimeMillis ( ) ; log . info ( "SNAPSHOT COMPLETED IN " + ( endTime - startTime ) + "ms" ) ; log . info ( "TYPES: " + typeNames ) ; notifyEndUpdate ( ) ; stateEngine . afterInitialization ( ) ;


signature:
public class HollowBlobReader { /** * Update the state engine using a delta ( or reverse delta ) blob from the provided InputStream .
 * If a { @ link HollowFilterConfig } was applied at the time the { @ link HollowReadStateEngine } was initialized
 * with a snapshot , it will continue to be in effect after the state is updated .
 * @ param is the input stream to read the delta from
 * @ throws IOException if the delta could not be applied */
public void applyDelta ( InputStream is ) throws IOException { } }

implementation: HollowBlobHeader header = readHeader ( is , true ) ; notifyBeginUpdate ( ) ; long startTime = System . currentTimeMillis ( ) ; DataInputStream dis = new DataInputStream ( is ) ; int numStates = VarInt . readVInt ( dis ) ; Collection < String > typeNames = new TreeSet < String > ( ) ; for ( int i = 0 ; i < numStates ; i ++ ) { String typeName = readTypeStateDelta ( dis , header ) ; typeNames . add ( typeName ) ; stateEngine . getMemoryRecycler ( ) . swap ( ) ; } long endTime = System . currentTimeMillis ( ) ; log . info ( "DELTA COMPLETED IN " + ( endTime - startTime ) + "ms" ) ; log . info ( "TYPES: " + typeNames ) ; notifyEndUpdate ( ) ;


signature:
public class DiffViewOutputGenerator { /** * Returns a String representation of the provided row ' s field value . If ` useFrom ` is
 * true , this will use the ` from ` value from the pair , otherwise this will use the
 * ` to ` value . */
private static String getFieldValue ( HollowDiffViewRow row , boolean useFrom ) { } }

implementation: Field field = useFrom ? row . getFieldPair ( ) . getFrom ( ) : row . getFieldPair ( ) . getTo ( ) ; if ( row . getFieldPair ( ) . isLeafNode ( ) ) { return field . getValue ( ) == null ? "null" : field . getValue ( ) . toString ( ) . replace ( "|" , "&#x2502" ) ; } else { String suffix = field . getValue ( ) == null ? " [null]" : "" ; return "(" + field . getTypeName ( ) + ")" + suffix ; }


signature:
public class SegmentedByteArray { /** * Set the byte at the given index to the specified value
 * @ param index the index
 * @ param value the byte value */
public void set ( long index , byte value ) { } }

implementation: int segmentIndex = ( int ) ( index >> log2OfSegmentSize ) ; ensureCapacity ( segmentIndex ) ; segments [ segmentIndex ] [ ( int ) ( index & bitmask ) ] = value ;


signature:
public class SegmentedByteArray { /** * Copy bytes from another ByteData to this array .
 * @ param src the source data
 * @ param srcPos the position to begin copying from the source data
 * @ param destPos the position to begin writing in this array
 * @ param length the length of the data to copy */
public void copy ( ByteData src , long srcPos , long destPos , long length ) { } }

implementation: for ( long i = 0 ; i < length ; i ++ ) { set ( destPos ++ , src . get ( srcPos ++ ) ) ; }


signature:
public class SegmentedByteArray { /** * copies exactly data . length bytes from this SegmentedByteArray into the provided byte array
 * @ param srcPos the position to begin copying from the source data
 * @ param data the source data
 * @ param destPos the position to begin writing in this array
 * @ param length the length of the data to copy
 * @ return the number of bytes copied */
public int copy ( long srcPos , byte [ ] data , int destPos , int length ) { } }

implementation: int segmentSize = 1 << log2OfSegmentSize ; int remainingBytesInSegment = ( int ) ( segmentSize - ( srcPos & bitmask ) ) ; int dataPosition = destPos ; while ( length > 0 ) { byte [ ] segment = segments [ ( int ) ( srcPos >>> log2OfSegmentSize ) ] ; int bytesToCopyFromSegment = Math . min ( remainingBytesInSegment , length ) ; System . arraycopy ( segment , ( int ) ( srcPos & bitmask ) , data , dataPosition , bytesToCopyFromSegment ) ; dataPosition += bytesToCopyFromSegment ; srcPos += bytesToCopyFromSegment ; remainingBytesInSegment = segmentSize - ( int ) ( srcPos & bitmask ) ; length -= bytesToCopyFromSegment ; } return dataPosition - destPos ;


signature:
public class SegmentedByteArray { /** * checks equality for a specified range of bytes in two arrays
 * @ param rangeStart the start position of the comparison range in this array
 * @ param compareTo the other array to compare
 * @ param cmpStart the start position of the comparison range in the other array
 * @ param length the length of the comparison range
 * @ return */
public boolean rangeEquals ( long rangeStart , SegmentedByteArray compareTo , long cmpStart , int length ) { } }

implementation: for ( int i = 0 ; i < length ; i ++ ) if ( get ( rangeStart + i ) != compareTo . get ( cmpStart + i ) ) return false ; return true ;


signature:
public class SegmentedByteArray { /** * Copies the data from the provided source array into this array , guaranteeing that
 * if the update is seen by another thread , then all other writes prior to this call
 * are also visible to that thread .
 * @ param src the source data
 * @ param srcPos the position to begin copying from the source data
 * @ param destPos the position to begin writing in this array
 * @ param length the length of the data to copy */
public void orderedCopy ( SegmentedByteArray src , long srcPos , long destPos , long length ) { } }

implementation: int segmentLength = 1 << log2OfSegmentSize ; int currentSegment = ( int ) ( destPos >>> log2OfSegmentSize ) ; int segmentStartPos = ( int ) ( destPos & bitmask ) ; int remainingBytesInSegment = segmentLength - segmentStartPos ; while ( length > 0 ) { int bytesToCopyFromSegment = ( int ) Math . min ( remainingBytesInSegment , length ) ; ensureCapacity ( currentSegment ) ; int copiedBytes = src . orderedCopy ( srcPos , segments [ currentSegment ] , segmentStartPos , bytesToCopyFromSegment ) ; srcPos += copiedBytes ; length -= copiedBytes ; segmentStartPos = 0 ; remainingBytesInSegment = segmentLength ; currentSegment ++ ; }


signature:
public class SegmentedByteArray { /** * copies exactly data . length bytes from this SegmentedByteArray into the provided byte array ,
 * guaranteeing that if the update is seen by another thread , then all other writes prior to
 * this call are also visible to that thread .
 * @ param srcPos the position to begin copying from the source data
 * @ param data the source data
 * @ param destPos the position to begin writing in this array
 * @ param length the length of the data to copy
 * @ return the number of bytes copied */
public int orderedCopy ( long srcPos , byte [ ] data , int destPos , int length ) { } }

implementation: int segmentSize = 1 << log2OfSegmentSize ; int remainingBytesInSegment = ( int ) ( segmentSize - ( srcPos & bitmask ) ) ; int dataPosition = destPos ; while ( length > 0 ) { byte [ ] segment = segments [ ( int ) ( srcPos >>> log2OfSegmentSize ) ] ; int bytesToCopyFromSegment = Math . min ( remainingBytesInSegment , length ) ; orderedCopy ( segment , ( int ) ( srcPos & bitmask ) , data , dataPosition , bytesToCopyFromSegment ) ; dataPosition += bytesToCopyFromSegment ; srcPos += bytesToCopyFromSegment ; remainingBytesInSegment = segmentSize - ( int ) ( srcPos & bitmask ) ; length -= bytesToCopyFromSegment ; } return dataPosition - destPos ;


signature:
public class SegmentedByteArray { /** * Copy bytes from the supplied InputStream into this array .
 * @ param is the source data
 * @ param length the length of the data to copy
 * @ throws IOException if the copy could not be performed */
public void readFrom ( InputStream is , long length ) throws IOException { } }

implementation: int segmentSize = 1 << log2OfSegmentSize ; int segment = 0 ; byte scratch [ ] = new byte [ segmentSize ] ; while ( length > 0 ) { ensureCapacity ( segment ) ; long bytesToCopy = Math . min ( segmentSize , length ) ; long bytesCopied = 0 ; while ( bytesCopied < bytesToCopy ) { bytesCopied += is . read ( scratch , ( int ) bytesCopied , ( int ) ( bytesToCopy - bytesCopied ) ) ; } orderedCopy ( scratch , 0 , segments [ segment ++ ] , 0 , ( int ) bytesCopied ) ; length -= bytesCopied ; }


signature:
public class SegmentedByteArray { /** * Write a portion of this data to an OutputStream .
 * @ param os the output stream to write to
 * @ param startPosition the position to begin copying from this array
 * @ param len the length of the data to copy
 * @ throws IOException if the write to the output stream could not be performed */
public void writeTo ( OutputStream os , long startPosition , long len ) throws IOException { } }

implementation: int segmentSize = 1 << log2OfSegmentSize ; int remainingBytesInSegment = segmentSize - ( int ) ( startPosition & bitmask ) ; long remainingBytesInCopy = len ; while ( remainingBytesInCopy > 0 ) { long bytesToCopyFromSegment = Math . min ( remainingBytesInSegment , remainingBytesInCopy ) ; os . write ( segments [ ( int ) ( startPosition >>> log2OfSegmentSize ) ] , ( int ) ( startPosition & bitmask ) , ( int ) bytesToCopyFromSegment ) ; startPosition += bytesToCopyFromSegment ; remainingBytesInSegment = segmentSize - ( int ) ( startPosition & bitmask ) ; remainingBytesInCopy -= bytesToCopyFromSegment ; }


signature:
public class SegmentedByteArray { /** * Ensures that the segment at segmentIndex exists
 * @ param segmentIndex the segment index */
private void ensureCapacity ( int segmentIndex ) { } }

implementation: while ( segmentIndex >= segments . length ) { segments = Arrays . copyOf ( segments , segments . length * 3 / 2 ) ; } if ( segments [ segmentIndex ] == null ) { segments [ segmentIndex ] = memoryRecycler . getByteArray ( ) ; }


signature:
public class HollowObjectSchema { /** * Returns the position of a field previously added to the map , or - 1 if the field has not been added to the map .
 * The positions of the fields are hashed into the < code > hashedPositionArray < / code > by the hashCode of the fieldName .
 * @ param fieldName the field name
 * @ return the position */
public int getPosition ( String fieldName ) { } }

implementation: Integer index = nameFieldIndexLookup . get ( fieldName ) ; if ( index == null ) { return - 1 ; } return index ;


signature:
public class HollowHashIndexBuilder { /** * Called after initial pass .
 * Returns the sum total number of select buckets in the low 7 bytes , and the bits required for the max set size in the high 1 byte . */
private long calculateDedupedSizesAndTotalNumberOfSelectBuckets ( MultiLinkedElementArray elementArray , GrowingSegmentedLongArray matchIndexHashAndSizeArray ) { } }

implementation: long totalBuckets = 0 ; long maxSize = 0 ; int [ ] selectArray = new int [ 8 ] ; for ( int i = 0 ; i < elementArray . numLists ( ) ; i ++ ) { int listSize = elementArray . listSize ( i ) ; int setSize = 0 ; int predictedBuckets = HashCodes . hashTableSize ( listSize ) ; int hashMask = predictedBuckets - 1 ; if ( predictedBuckets > selectArray . length ) selectArray = new int [ predictedBuckets ] ; for ( int j = 0 ; j < predictedBuckets ; j ++ ) selectArray [ j ] = - 1 ; HollowOrdinalIterator iter = elementArray . iterator ( i ) ; int selectOrdinal = iter . next ( ) ; while ( selectOrdinal != HollowOrdinalIterator . NO_MORE_ORDINALS ) { int hash = HashCodes . hashInt ( selectOrdinal ) ; int bucket = hash & hashMask ; while ( true ) { if ( selectArray [ bucket ] == selectOrdinal ) break ; if ( selectArray [ bucket ] == - 1 ) { selectArray [ bucket ] = selectOrdinal ; setSize ++ ; break ; } bucket = ( bucket + 1 ) & hashMask ; } selectOrdinal = iter . next ( ) ; } long matchIndexHashAndSize = matchIndexHashAndSizeArray . get ( i ) ; matchIndexHashAndSize |= ( long ) setSize << 32 ; matchIndexHashAndSizeArray . set ( i , matchIndexHashAndSize ) ; totalBuckets += HashCodes . hashTableSize ( setSize ) ; if ( setSize > maxSize ) maxSize = setSize ; } return totalBuckets | ( long ) bitsRequiredToRepresentValue ( maxSize ) << 56 ;


signature:
public class HollowAPIGenerator { /** * Usage : java HollowAPIGenerator - - argName1 = argValue1 - - argName2 = = argValue2 . See { @ link GeneratorArguments } for
 * available arguments .
 * @ param args the arguments
 * @ throws IOException if a schema could not be read or the data model written
 * @ throws ClassNotFoundException if a class of a data model cannot be loaded */
public static void main ( String [ ] args ) throws IOException , ClassNotFoundException { } }

implementation: if ( args . length == 0 ) { System . out . println ( "Usage:\n" + "java " + HollowAPIGenerator . class . getName ( ) + " --arg1=value1 --arg2=value2\n" + "see " + GeneratorArguments . class . getName ( ) + " for available arguments." ) ; return ; } HollowWriteStateEngine engine = new HollowWriteStateEngine ( ) ; HollowAPIGenerator . Builder builder = new HollowAPIGenerator . Builder ( ) ; HollowObjectMapper mapper = new HollowObjectMapper ( engine ) ; ArgumentParser < GeneratorArguments > argumentParser = new ArgumentParser ( GeneratorArguments . class , args ) ; for ( ArgumentParser < GeneratorArguments > . ParsedArgument arg : argumentParser . getParsedArguments ( ) ) { switch ( arg . getKey ( ) ) { case addToDataModel : mapper . initializeTypeState ( HollowAPIGenerator . class . getClassLoader ( ) . loadClass ( arg . getValue ( ) ) ) ; break ; case addSchemaFileToDataModel : HollowWriteStateCreator . readSchemaFileIntoWriteState ( arg . getValue ( ) , engine ) ; break ; case apiClassName : builder . withAPIClassname ( arg . getValue ( ) ) ; break ; case classPostfix : builder . withClassPostfix ( arg . getValue ( ) ) ; break ; case getterPrefix : builder . withGetterPrefix ( arg . getValue ( ) ) ; break ; case packageName : builder . withPackageName ( arg . getValue ( ) ) ; break ; case pathToGeneratedFiles : builder . withDestination ( arg . getValue ( ) ) ; break ; case parameterizeAllClassNames : builder . withParameterizeAllClassNames ( Boolean . valueOf ( arg . getValue ( ) ) ) ; break ; default : throw new IllegalArgumentException ( "Unhandled argument " + arg . getKey ( ) ) ; } } builder . withDataModel ( engine ) . build ( ) . generateSourceFiles ( ) ;


signature:
public class HollowAPIGenerator { /** * Determines whether DataSet contains any collections schema
 * @ param dataset the data set
 * @ return { @ code true } if the data set contains any collections schema */
protected static boolean hasCollectionsInDataSet ( HollowDataset dataset ) { } }

implementation: for ( HollowSchema schema : dataset . getSchemas ( ) ) { if ( ( schema instanceof HollowListSchema ) || ( schema instanceof HollowSetSchema ) || ( schema instanceof HollowMapSchema ) ) { return true ; } } return false ;


signature:
public class HollowAPIGenerator { /** * Generate files under the specified directory
 * @ param directory the directory under which to generate files
 * @ throws IOException if the files cannot be generated
 * @ deprecated construct { @ code HollowAPIGenerator } with a { @ code destinationPath } then call { @ link # generateSourceFiles ( ) } */
public void generateFiles ( File directory ) throws IOException { } }

implementation: if ( packageName != null && ! packageName . trim ( ) . isEmpty ( ) ) { String packageDir = packageName . replace ( "." , File . separator ) ; if ( ! directory . getAbsolutePath ( ) . endsWith ( packageDir ) ) { directory = new File ( directory , packageDir ) ; } } directory . mkdirs ( ) ; HollowAPIClassJavaGenerator apiClassGenerator = new HollowAPIClassJavaGenerator ( packageName , apiClassname , dataset , parameterizeClassNames , config ) ; HollowAPIFactoryJavaGenerator apiFactoryGenerator = new HollowAPIFactoryJavaGenerator ( packageName , apiClassname , dataset , config ) ; HollowHashIndexGenerator hashIndexGenerator = new HollowHashIndexGenerator ( packageName , apiClassname , dataset , config ) ; generateFile ( directory , apiClassGenerator ) ; generateFile ( directory , apiFactoryGenerator ) ; generateFile ( directory , hashIndexGenerator ) ; generateFilesForHollowSchemas ( directory ) ;


signature:
public class HollowAPIGenerator { /** * Generate files based on dataset schemas under the specified directory
 * @ param directory the directory under which to generate files
 * @ throws IOException if the files cannot be generated
 * @ deprecated construct { @ code HollowAPIGenerator } with a { @ code destinationPath } then call { @ link # generateSourceFilesForHollowSchemas ( ) } */
protected void generateFilesForHollowSchemas ( File directory ) throws IOException { } }

implementation:
for ( HollowSchema schema : dataset . getSchemas ( ) ) { String type = schema . getName ( ) ; if ( config . isUseHollowPrimitiveTypes ( ) && HollowCodeGenerationUtils . isPrimitiveType ( type ) ) continue ; // skip if using hollow primitive type
generateFile ( directory , getStaticAPIGenerator ( schema ) ) ; generateFile ( directory , getHollowObjectGenerator ( schema ) ) ; generateFile ( directory , getHollowFactoryGenerator ( schema ) ) ; if ( schema . getSchemaType ( ) == SchemaType . OBJECT ) { HollowObjectSchema objSchema = ( HollowObjectSchema ) schema ; generateFile ( directory , new HollowObjectDelegateInterfaceGenerator ( packageName , objSchema , ergonomicShortcuts , dataset , config ) ) ; generateFile ( directory , new HollowObjectDelegateCachedImplGenerator ( packageName , objSchema , ergonomicShortcuts , dataset , config ) ) ; generateFile ( directory , new HollowObjectDelegateLookupImplGenerator ( packageName , objSchema , ergonomicShortcuts , dataset , config ) ) ; generateFile ( directory , new HollowDataAccessorGenerator ( packageName , apiClassname , objSchema , dataset , config ) ) ; if ( ! config . isReservePrimaryKeyIndexForTypeWithPrimaryKey ( ) ) { generateFile ( directory , new LegacyHollowPrimaryKeyIndexGenerator ( packageName , apiClassname , objSchema , dataset , config ) ) ; } else if ( ( objSchema ) . getPrimaryKey ( ) != null ) { generateFile ( directory , new HollowPrimaryKeyIndexGenerator ( dataset , packageName , apiClassname , objSchema , config ) ) ; generateFile ( directory , new HollowUniqueKeyIndexGenerator ( packageName , apiClassname , objSchema , dataset , config ) ) ; } } }


signature:
public class HollowPrimaryKeyValueDeriver { /** * Determine whether or not the specified ordinal contains the provided primary key value .
 * @ param ordinal the oridinal
 * @ param keys the primary keys
 * @ return true if the ordinal contains the primary keys */
public boolean keyMatches ( int ordinal , Object ... keys ) { } }

implementation: if ( keys . length != fieldPathIndexes . length ) return false ; for ( int i = 0 ; i < keys . length ; i ++ ) { if ( ! keyMatches ( keys [ i ] , ordinal , i ) ) return false ; } return true ;


signature:
public class HollowPrimaryKeyValueDeriver { /** * Retrieve the primary key value for the specified ordinal .
 * @ param ordinal the oridinal
 * @ return the primary keys */
public Object [ ] getRecordKey ( int ordinal ) { } }

implementation: Object [ ] results = new Object [ fieldPathIndexes . length ] ; for ( int i = 0 ; i < fieldPathIndexes . length ; i ++ ) { results [ i ] = readValue ( ordinal , i ) ; } return results ;


signature:
public class AbstractHollowProducer { /** * Initializes the data model for the given classes .
 * Data model initialization is required prior to { @ link # restore ( long , HollowConsumer . BlobRetriever ) restoring }
 * the producer .
 * This ensures that restoration can correctly compare the producer ' s current data model
 * with the data model of the restored data state and manage any differences in those models
 * ( such as not restoring state for any types in the restoring data model not present in the
 * producer ' s current data model ) .
 * After initialization a data model initialization event will be emitted
 * to all registered data model initialization listeners
 * { @ link com . netflix . hollow . api . producer . listener . DataModelInitializationListener listeners } .
 * @ param classes the data model classes
 * @ throws IllegalArgumentException if { @ code classes } is empty
 * @ see # restore ( long , HollowConsumer . BlobRetriever ) */
public void initializeDataModel ( Class < ? > ... classes ) { } }

implementation: Objects . requireNonNull ( classes ) ; if ( classes . length == 0 ) { throw new IllegalArgumentException ( "classes is empty" ) ; } long start = currentTimeMillis ( ) ; for ( Class < ? > c : classes ) { objectMapper . initializeTypeState ( c ) ; } listeners . listeners ( ) . fireProducerInit ( currentTimeMillis ( ) - start ) ; isInitialized = true ;


signature:
public class AbstractHollowProducer { /** * Initializes the producer data model for the given schemas .
 * Data model initialization is required prior to { @ link # restore ( long , HollowConsumer . BlobRetriever ) restoring }
 * the producer .
 * This ensures that restoration can correctly compare the producer ' s current data model
 * with the data model of the restored data state and manage any differences in those models
 * ( such as not restoring state for any types in the restoring data model not present in the
 * producer ' s current data model ) .
 * After initialization a data model initialization event will be emitted
 * to all registered data model initialization listeners
 * { @ link com . netflix . hollow . api . producer . listener . DataModelInitializationListener listeners } .
 * @ param schemas the data model classes
 * @ throws IllegalArgumentException if { @ code schemas } is empty
 * @ see # restore ( long , HollowConsumer . BlobRetriever ) */
public void initializeDataModel ( HollowSchema ... schemas ) { } }

implementation: Objects . requireNonNull ( schemas ) ; if ( schemas . length == 0 ) { throw new IllegalArgumentException ( "classes is empty" ) ; } long start = currentTimeMillis ( ) ; HollowWriteStateCreator . populateStateEngineWithTypeWriteStates ( getWriteEngine ( ) , Arrays . asList ( schemas ) ) ; listeners . listeners ( ) . fireProducerInit ( currentTimeMillis ( ) - start ) ; isInitialized = true ;


signature:
public class AbstractHollowProducer { /** * Restores the data state to a desired version .
 * Data model { @ link # initializeDataModel ( Class [ ] ) initialization } is required prior to
 * restoring the producer . This ensures that restoration can correctly compare the producer ' s
 * current data model with the data model of the restored data state and manage any differences
 * in those models ( such as not restoring state for any types in the restoring data model not
 * present in the producer ' s current data model )
 * @ param versionDesired the desired version
 * @ param blobRetriever the blob retriever
 * @ return the read state of the restored state
 * @ throws IllegalStateException if the producer ' s data model has not been initialized
 * @ see # initializeDataModel ( Class [ ] ) */
public HollowProducer . ReadState restore ( long versionDesired , HollowConsumer . BlobRetriever blobRetriever ) { } }

implementation: return restore ( versionDesired , blobRetriever , ( restoreFrom , restoreTo ) -> restoreTo . restoreFrom ( restoreFrom ) ) ;


signature:
public class AbstractHollowProducer { /** * Invoke this method to alter runCycle behavior . If this Producer is not primary , runCycle is a no - op . Note that by default ,
 * SingleProducerEnforcer is instantiated as BasicSingleProducerEnforcer , which is initialized to return true for isPrimary ( )
 * @ param doEnable true if enable primary producer , if false
 * @ return true if the intended action was successful */
public boolean enablePrimaryProducer ( boolean doEnable ) { } }

implementation: if ( doEnable ) { singleProducerEnforcer . enable ( ) ; } else { singleProducerEnforcer . disable ( ) ; } return ( singleProducerEnforcer . isPrimary ( ) == doEnable ) ;


signature:
public class AbstractHollowProducer { /** * Publish the write state , storing the artifacts in the provided object . Visible for testing . */
void publish ( ListenerSupport . Listeners listeners , long toVersion , Artifacts artifacts ) throws IOException { } }

implementation:
Status . StageBuilder psb = listeners . firePublishStart ( toVersion ) ; try { artifacts . snapshot = stageBlob ( listeners , blobStager . openSnapshot ( toVersion ) ) ; if ( readStates . hasCurrent ( ) ) { artifacts . delta = stageBlob ( listeners , blobStager . openDelta ( readStates . current ( ) . getVersion ( ) , toVersion ) ) ; artifacts . reverseDelta = stageBlob ( listeners , blobStager . openReverseDelta ( toVersion , readStates . current ( ) . getVersion ( ) ) ) ; publishBlob ( listeners , artifacts . delta ) ; publishBlob ( listeners , artifacts . reverseDelta ) ; if ( -- numStatesUntilNextSnapshot < 0 ) { if ( snapshotPublishExecutor == null ) { publishBlob ( listeners , artifacts . snapshot ) ; artifacts . markSnapshotPublishComplete ( ) ; } else { // Submit the publish blob task to the executor
publishSnapshotBlobAsync ( listeners , artifacts ) ; } numStatesUntilNextSnapshot = numStatesBetweenSnapshots ; } else { artifacts . markSnapshotPublishComplete ( ) ; } } else { publishBlob ( listeners , artifacts . snapshot ) ; artifacts . markSnapshotPublishComplete ( ) ; numStatesUntilNextSnapshot = numStatesBetweenSnapshots ; } psb . success ( ) ; } catch ( Throwable throwable ) { psb . fail ( throwable ) ; throw throwable ; } finally { listeners . firePublishComplete ( psb ) ; }


signature:
public class AbstractHollowProducer { /** * Given these read states
 * * S ( cur ) at the currently announced version
 * * S ( pnd ) at the pending version
 * Ensure that :
 * S ( cur ) . apply ( forwardDelta ) . checksum = = S ( pnd ) . checksum
 * S ( pnd ) . apply ( reverseDelta ) . checksum = = S ( cur ) . checksum
 * @ return updated read states */
private ReadStateHelper checkIntegrity ( ListenerSupport . Listeners listeners , ReadStateHelper readStates , Artifacts artifacts ) throws Exception { } }

implementation:
Status . StageWithStateBuilder status = listeners . fireIntegrityCheckStart ( readStates . pending ( ) ) ; try { ReadStateHelper result = readStates ; HollowReadStateEngine pending = readStates . pending ( ) . getStateEngine ( ) ; readSnapshot ( artifacts . snapshot , pending ) ; if ( readStates . hasCurrent ( ) ) { HollowReadStateEngine current = readStates . current ( ) . getStateEngine ( ) ; log . info ( "CHECKSUMS" ) ; HollowChecksum currentChecksum = HollowChecksum . forStateEngineWithCommonSchemas ( current , pending ) ; log . info ( "  CUR        " + currentChecksum ) ; HollowChecksum pendingChecksum = HollowChecksum . forStateEngineWithCommonSchemas ( pending , current ) ; log . info ( "         PND " + pendingChecksum ) ; if ( artifacts . hasDelta ( ) ) { if ( ! artifacts . hasReverseDelta ( ) ) { throw new IllegalStateException ( "Both a delta and reverse delta are required" ) ; } // FIXME : timt : future cycles will fail unless both deltas validate
applyDelta ( artifacts . delta , current ) ; HollowChecksum forwardChecksum = HollowChecksum . forStateEngineWithCommonSchemas ( current , pending ) ; // out . format ( " CUR = > PND % s \ n " , forwardChecksum ) ;
if ( ! forwardChecksum . equals ( pendingChecksum ) ) { throw new HollowProducer . ChecksumValidationException ( HollowProducer . Blob . Type . DELTA ) ; } applyDelta ( artifacts . reverseDelta , pending ) ; HollowChecksum reverseChecksum = HollowChecksum . forStateEngineWithCommonSchemas ( pending , current ) ; // out . format ( " CUR < = PND % s \ n " , reverseChecksum ) ;
if ( ! reverseChecksum . equals ( currentChecksum ) ) { throw new HollowProducer . ChecksumValidationException ( HollowProducer . Blob . Type . REVERSE_DELTA ) ; } result = readStates . swap ( ) ; } } status . success ( ) ; return result ; } catch ( Throwable th ) { status . fail ( th ) ; throw th ; } finally { listeners . fireIntegrityCheckComplete ( status ) ; }


signature:
public class HollowReadStateEngine { /** * Add a { @ link HollowTypeStateListener } to a type .
 * @ param typeName the type name
 * @ param listener the listener to add */
public void addTypeListener ( String typeName , HollowTypeStateListener listener ) { } }

implementation: List < HollowTypeStateListener > list = listeners . get ( typeName ) ; if ( list == null ) { list = new ArrayList < HollowTypeStateListener > ( ) ; listeners . put ( typeName , list ) ; } list . add ( listener ) ; HollowTypeReadState typeState = typeStates . get ( typeName ) ; if ( typeState != null ) typeState . addListener ( listener ) ;


signature:
public class FieldPaths { /** * Creates an object - based field path given a data set and the field path in symbolic form conforming to paths
 * associated with a primary key .
 * @ param dataset the data set
 * @ param type the type name from which to bind the field path
 * @ param path the symbolic field path
 * @ return the field path
 * @ throws IllegalArgumentException if the symbolic field path is ill - formed and cannot be bound */
public static FieldPath < ObjectFieldSegment > createFieldPathForPrimaryKey ( HollowDataset dataset , String type , String path ) { } }

implementation:
boolean autoExpand = ! path . endsWith ( "!" ) ; path = autoExpand ? path : path . substring ( 0 , path . length ( ) - 1 ) ; FieldPath < FieldSegment > fp = createFieldPath ( dataset , type , path , autoExpand , false , false ) ; // Erasure trick to avoid copying when it is known the list only contains
// instances of ObjectFieldSegment
assert fp . segments . stream ( ) . allMatch ( o -> o instanceof ObjectFieldSegment ) ; @ SuppressWarnings ( { "unchecked" , "raw" } ) FieldPath < ObjectFieldSegment > result = ( FieldPath < ObjectFieldSegment > ) ( FieldPath ) fp ; return result ;


signature:
public class FieldPaths { /** * Creates a field path given a data set and the field path in symbolic form conforming to paths
 * associated with a hash index .
 * @ param dataset the data set
 * @ param type the type name from which to bind the field path
 * @ param path the symbolic field path
 * @ return the field path
 * @ throws IllegalArgumentException if the symbolic field path is ill - formed and cannot be bound */
public static FieldPath < FieldSegment > createFieldPathForHashIndex ( HollowDataset dataset , String type , String path ) { } }

implementation: return createFieldPath ( dataset , type , path , false , false , true ) ;


signature:
public class FieldPaths { /** * Creates a field path given a data set and the field path in symbolic form conforming to paths
 * associated with a prefix index .
 * @ param dataset the data set
 * @ param type the type name from which to bind the field path
 * @ param path the symbolic field path
 * @ param autoExpand { @ code true } if the field path should be expanded ( if needed ) to a full path referencing
 * an object field whose type is a non - reference type , otherwise the field path is not expanded and must be
 * a full path
 * @ return the field path
 * @ throws IllegalArgumentException if the symbolic field path is ill - formed and cannot be bound */
public static FieldPath < FieldSegment > createFieldPathForPrefixIndex ( HollowDataset dataset , String type , String path , boolean autoExpand ) { } }

implementation:
// If autoExpand is false then requireFullPath must be true
boolean requireFullPath = ! autoExpand ; return createFieldPath ( dataset , type , path , autoExpand , requireFullPath , true ) ;


signature:
public class FieldPaths { /** * Creates a field path given a data set and the field path in symbolic form .
 * @ param dataset the data set
 * @ param type the type name from which to bind the field path
 * @ param path the symbolic field path
 * @ param autoExpand { @ code true } if the field path should be expanded ( if needed ) to a full path referencing
 * an object field whose type is a non - reference type , otherwise the field path is not expanded
 * @ param requireFullPath { @ code true } if a full path is required when { @ code autoExpand } is { @ code false } .
 * Ignored if { @ code autoExpand } is { @ code true } .
 * @ param traverseSequences { @ code true } if lists , sets and maps are traversed , otherwise an
 * { @ code IllegalArgumentException } will be thrown
 * @ return the field path
 * @ throws IllegalArgumentException if the symbolic field path is ill - formed and cannot be bound */
static FieldPath < FieldSegment > createFieldPath ( HollowDataset dataset , String type , String path , boolean autoExpand , boolean requireFullPath , boolean traverseSequences ) { } }

implementation:
Objects . requireNonNull ( dataset ) ; Objects . requireNonNull ( type ) ; Objects . requireNonNull ( path ) ; String [ ] segments = path . isEmpty ( ) ? new String [ 0 ] : path . split ( "\\." ) ; List < FieldSegment > fieldSegments = new ArrayList < > ( ) ; String segmentType = type ; for ( int i = 0 ; i < segments . length ; i ++ ) { HollowSchema schema = dataset . getSchema ( segmentType ) ; // @ @ @ Can this only occur for anything other than the root ` type ` ?
if ( schema == null ) { throw new FieldPathException ( FieldPathException . ErrorKind . NOT_BINDABLE , dataset , type , segments , fieldSegments , null , i ) ; } String segment = segments [ i ] ; HollowSchema . SchemaType schemaType = schema . getSchemaType ( ) ; if ( schemaType == HollowSchema . SchemaType . OBJECT ) { HollowObjectSchema objectSchema = ( HollowObjectSchema ) schema ; int index = objectSchema . getPosition ( segment ) ; if ( index == - 1 ) { throw new FieldPathException ( FieldPathException . ErrorKind . NOT_FOUND , dataset , type , segments , fieldSegments , schema , i ) ; } segmentType = objectSchema . getReferencedType ( index ) ; fieldSegments . add ( new ObjectFieldSegment ( objectSchema , segment , segmentType , index ) ) ; } else if ( traverseSequences && ( schemaType == HollowSchema . SchemaType . SET || schemaType == HollowSchema . SchemaType . LIST ) ) { HollowCollectionSchema collectionSchema = ( HollowCollectionSchema ) schema ; if ( ! segment . equals ( "element" ) ) { throw new FieldPathException ( FieldPathException . ErrorKind . NOT_FOUND , dataset , type , segments , fieldSegments , schema , i ) ; } segmentType = collectionSchema . getElementType ( ) ; fieldSegments . add ( new FieldSegment ( collectionSchema , segment , segmentType ) ) ; } else if ( traverseSequences && schemaType == HollowSchema . SchemaType . MAP ) { HollowMapSchema mapSchema = ( HollowMapSchema ) schema ; if ( segment . equals ( "key" ) ) { segmentType = mapSchema . getKeyType ( ) ; } else if ( segment . equals ( "value" ) ) { segmentType = mapSchema . getValueType ( ) ; } else { throw new FieldPathException ( FieldPathException . ErrorKind . NOT_FOUND , dataset , type , segments , fieldSegments , schema , i ) ; } fieldSegments . add ( new FieldSegment ( mapSchema , segment , segmentType ) ) ; } else if ( ! traverseSequences ) { throw new FieldPathException ( FieldPathException . ErrorKind . NOT_TRAVERSABLE , dataset , type , segments , fieldSegments , schema , i ) ; } if ( i < segments . length - 1 && segmentType == null ) { throw new FieldPathException ( FieldPathException . ErrorKind . NOT_TRAVERSABLE , dataset , type , segments , fieldSegments , schema , i ) ; } } if ( autoExpand ) { while ( segmentType != null ) { HollowSchema schema = dataset . getSchema ( segmentType ) ; if ( schema . getSchemaType ( ) == HollowSchema . SchemaType . OBJECT ) { HollowObjectSchema objectSchema = ( HollowObjectSchema ) schema ; if ( objectSchema . numFields ( ) == 1 ) { segmentType = objectSchema . getReferencedType ( 0 ) ; fieldSegments . add ( new ObjectFieldSegment ( objectSchema , objectSchema . getFieldName ( 0 ) , segmentType , 0 ) ) ; } else if ( objectSchema . getPrimaryKey ( ) != null && objectSchema . getPrimaryKey ( ) . numFields ( ) == 1 ) { PrimaryKey key = objectSchema . getPrimaryKey ( ) ; FieldPath < ObjectFieldSegment > expandedFieldSegments ; try { expandedFieldSegments = createFieldPathForPrimaryKey ( dataset , key . getType ( ) , key . getFieldPaths ( ) [ 0 ] ) ; } catch ( FieldPathException cause ) { FieldPathException e = new FieldPathException ( FieldPathException . ErrorKind . NOT_EXPANDABLE , dataset , type , segments , fieldSegments , objectSchema ) ; e . initCause ( cause ) ; throw e ; } fieldSegments . addAll ( expandedFieldSegments . segments ) ; break ; } else { throw new FieldPathException ( FieldPathException . ErrorKind . NOT_EXPANDABLE , dataset , type , segments , fieldSegments , objectSchema ) ; } } else { throw new FieldPathException ( FieldPathException . ErrorKind . NOT_EXPANDABLE , dataset , type , segments , fieldSegments , schema ) ; } } } else if ( requireFullPath && segmentType != null ) { throw new FieldPathException ( FieldPathException . ErrorKind . NOT_FULL , dataset , type , segments , fieldSegments ) ; } return new FieldPath < > ( type , fieldSegments , ! autoExpand ) ;


signature:
public class ObjectIdentityOrdinalMap { /** * Associating the obj with an ordinal
 * @ param obj
 * @ param ordinal */
public void put ( Object obj , int ordinal ) { } }

implementation: int hashCode = System . identityHashCode ( obj ) ; int segment = segment ( hashCode ) ; segments [ segment ] . put ( obj , hashCode , ordinal ) ;


signature:
public class HollowUpdatePlanner { /** * Returns an update plan that if executed will update the client to a version that is either equal to or as close to but
 * less than the desired version as possible . This plan normally contains one snapshot transition and zero or more delta
 * transitions but if no previous versions were found then an empty plan , { @ code HollowUpdatePlan . DO _ NOTHING } , is returned .
 * @ param desiredVersion The desired version to which the client wishes to update to , or update to as close to as possible but lesser than this version
 * @ return An update plan containing 1 snapshot transition and 0 + delta transitions if requested versions were found ,
 * or an empty plan , { @ code HollowUpdatePlan . DO _ NOTHING } , if no previous versions were found */
private HollowUpdatePlan snapshotPlan ( long desiredVersion ) { } }

implementation:
HollowUpdatePlan plan = new HollowUpdatePlan ( ) ; long nearestPreviousSnapshotVersion = includeNearestSnapshot ( plan , desiredVersion ) ; // The includeNearestSnapshot function returns a snapshot version that is less than or equal to the desired version
if ( nearestPreviousSnapshotVersion > desiredVersion ) return HollowUpdatePlan . DO_NOTHING ; // If the nearest snapshot version is { @ code HollowConstants . VERSION _ LATEST } then no past snapshots were found , so
// skip the delta planning and the update plan does nothing
if ( nearestPreviousSnapshotVersion == HollowConstants . VERSION_LATEST ) return HollowUpdatePlan . DO_NOTHING ; plan . appendPlan ( deltaPlan ( nearestPreviousSnapshotVersion , desiredVersion , Integer . MAX_VALUE ) ) ; return plan ;


signature:
public class HollowUpdatePlanner { /** * Includes the next delta only if it will not take us * after * the desired version */
private long includeNextDelta ( HollowUpdatePlan plan , long currentVersion , long desiredVersion ) { } }

implementation: HollowConsumer . Blob transition = transitionCreator . retrieveDeltaBlob ( currentVersion ) ; if ( transition != null ) { if ( transition . getToVersion ( ) <= desiredVersion ) { plan . add ( transition ) ; } return transition . getToVersion ( ) ; } return HollowConstants . VERSION_LATEST ;


signature:
public class HollowPrefixIndex { /** * initialize field positions and field paths . */
private void initialize ( ) { } }

implementation:
String lastRefType = this . fieldPath . getLastRefTypeInPath ( ) ; // get all cardinality to estimate size of array bits needed .
totalWords = readStateEngine . getTypeState ( lastRefType ) . getPopulatedOrdinals ( ) . cardinality ( ) ; averageWordLen = 0 ; double avg = 0 ; HollowObjectTypeReadState objectTypeReadState = ( HollowObjectTypeReadState ) readStateEngine . getTypeState ( lastRefType ) ; BitSet keyBitSet = objectTypeReadState . getPopulatedOrdinals ( ) ; int ordinal = keyBitSet . nextSetBit ( 0 ) ; while ( ordinal != - 1 ) { avg += ( ( double ) objectTypeReadState . readString ( ordinal , 0 ) . length ( ) ) / ( ( double ) objectTypeReadState . maxOrdinal ( ) ) ; ordinal = keyBitSet . nextSetBit ( ordinal + 1 ) ; } averageWordLen = ( int ) Math . ceil ( avg ) ; HollowObjectTypeReadState valueState = ( HollowObjectTypeReadState ) readStateEngine . getTypeDataAccess ( type ) ; maxOrdinalOfType = valueState . maxOrdinal ( ) ; // initialize the prefix index .
build ( ) ;


signature:
public class HollowPrefixIndex { /** * Return the key to index in prefix index . Override this method to support tokens for the key . By default keys are indexed as lower case characters .
 * < pre > { @ code
 * String [ ] keys = super . getKey ( ordinal ) ;
 * String [ ] tokens = keys [ 0 ] . split ( " " )
 * return tokens ;
 * } < / pre >
 * @ param ordinal ordinal of the parent type .
 * @ return keys to index . */
protected String [ ] getKeys ( int ordinal ) { } }

implementation: Object [ ] values = fieldPath . findValues ( ordinal ) ; String [ ] stringValues = new String [ values . length ] ; for ( int i = 0 ; i < values . length ; i ++ ) { stringValues [ i ] = ( ( String ) values [ i ] ) . toLowerCase ( ) ; } return stringValues ;


signature:
public class HollowPrefixIndex { /** * Query the index to find all the ordinals that match the given prefix . Example -
 * < pre > { @ code
 * HollowOrdinalIterator iterator = index . findKeysWithPrefix ( " a " ) ;
 * int ordinal = iterator . next ( ) ;
 * while ( ordinal ! = HollowOrdinalIterator . NO _ MORE _ ORDINAL ) {
 * / / print the result using API
 * } < / pre >
 * For larger data sets , querying smaller prefixes will be longer than querying for prefixes that are longer .
 * @ param prefix findKeysWithPrefix prefix .
 * @ return An instance of HollowOrdinalIterator to iterate over ordinals that match the given findKeysWithPrefix . */
@ SuppressWarnings ( "WeakerAccess" ) public HollowOrdinalIterator findKeysWithPrefix ( String prefix ) { } }

implementation: TST current ; HollowOrdinalIterator it ; do { current = prefixIndexVolatile ; it = current . findKeysWithPrefix ( prefix ) ; } while ( current != this . prefixIndexVolatile ) ; return it ;


signature:
public class HollowPrefixIndex { /** * Check if the given key exists in the index .
 * @ param key the key
 * @ return { @ code true } if the key exists , otherwise { @ code false } */
public boolean contains ( String key ) { } }

implementation: if ( key == null ) throw new IllegalArgumentException ( "key cannot be null" ) ; TST current ; boolean result ; do { current = prefixIndexVolatile ; result = current . contains ( key ) ; } while ( current != this . prefixIndexVolatile ) ; return result ;


signature:
public class RecordCountVarianceValidator { /** * protected for tests */
float getChangePercent ( int latestCardinality , int previousCardinality ) { } }

implementation: int diff = Math . abs ( latestCardinality - previousCardinality ) ; return ( 100.0f * diff ) / previousCardinality ;


signature:
public class HollowFilterConfig { /** * Add a type , plus recursively add any directly or transitively referenced types .
 * All fields in these types will be either excluded or included , depending on whether
 * this is an exclude or include filter , respectively .
 * @ param type A type from the data model .
 * @ param schemas All schemas from the data model . */
public void addTypeRecursive ( String type , Collection < HollowSchema > schemas ) { } }

implementation: addTypeRecursive ( type , mapSchemas ( schemas ) ) ;


signature:
public class HollowFilterConfig { /** * Add a type , plus recursively add any directly or transitively referenced types .
 * All fields in these types will be either excluded or included , depending on whether
 * this is an exclude or include filter , respectively .
 * @ param type A type from the data model .
 * @ param schemas A map of typeName to schema including all schemas for this data model . */
public void addTypeRecursive ( String type , Map < String , HollowSchema > schemas ) { } }

implementation: addType ( type ) ; HollowSchema schema = schemas . get ( type ) ; switch ( schema . getSchemaType ( ) ) { case OBJECT : HollowObjectSchema objSchema = ( HollowObjectSchema ) schema ; for ( int i = 0 ; i < objSchema . numFields ( ) ; i ++ ) { if ( objSchema . getFieldType ( i ) == FieldType . REFERENCE ) addTypeRecursive ( objSchema . getReferencedType ( i ) , schemas ) ; } break ; case MAP : addTypeRecursive ( ( ( HollowMapSchema ) schema ) . getKeyType ( ) , schemas ) ; addTypeRecursive ( ( ( HollowMapSchema ) schema ) . getValueType ( ) , schemas ) ; break ; case LIST : case SET : addTypeRecursive ( ( ( HollowCollectionSchema ) schema ) . getElementType ( ) , schemas ) ; break ; }


signature:
public class HollowFilterConfig { /** * Add an individual field from an OBJECT schema . This field will be either
 * excluded or included , depending on whether this is an exclude or include filter , respectively .
 * @ param type The OBJECT type from the data model
 * @ param objectField The field in the specified type to either include or exclude . */
public void addField ( String type , String objectField ) { } }

implementation: ObjectFilterConfig typeConfig = specifiedFieldConfigs . get ( type ) ; if ( typeConfig == null ) { typeConfig = new ObjectFilterConfig ( ) ; specifiedFieldConfigs . put ( type , typeConfig ) ; } typeConfig . addField ( objectField ) ;


signature:
public class HollowFilterConfig { /** * Add an individual field from an OBJECT schema , plus recursively add any directly or transitively referenced types .
 * This field will be either excluded or included , depending on whether this is an exclude or include filter , respectively .
 * @ param type The OBJECT type from the data model
 * @ param objectField The field in the specified type to either include or exclude .
 * @ param schemas All schemas from the data model . */
public void addFieldRecursive ( String type , String objectField , Collection < HollowSchema > schemas ) { } }

implementation: addFieldRecursive ( type , objectField , mapSchemas ( schemas ) ) ;


signature:
public class HollowFilterConfig { /** * Add an individual field from an OBJECT schema , plus recursively add any directly or transitively referenced types .
 * This field will be either excluded or included , depending on whether this is an exclude or include filter , respectively .
 * @ param type The OBJECT type from the data model
 * @ param objectField The field in the specified type to either include or exclude .
 * @ param schemas A map of typeName to schema including all schemas for this data model . */
public void addFieldRecursive ( String type , String objectField , Map < String , HollowSchema > schemas ) { } }

implementation: addField ( type , objectField ) ; HollowObjectSchema schema = ( HollowObjectSchema ) schemas . get ( type ) ; if ( schema . getFieldType ( objectField ) == FieldType . REFERENCE ) { addTypeRecursive ( schema . getReferencedType ( objectField ) , schemas ) ; }