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);
                }
            }
        }
    }
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>