hollow/src/main/java/com/netflix/hollow/tools/compact/HollowCompactor.java
public void compact() {
        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);
                }
            }
        }
    }
public void compact() {
        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);
                }
            }
        }
    }
public void compact ( ) { 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 ) ; } } } }
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>
Perform a compaction . It is expected that :