h2/src/main/org/h2/mvstore/MVStore.java
/**
     * Try to reduce the file size by re-writing partially full chunks. Chunks
     * with a low number of live items are re-written. If the current fill rate
     * is higher than the target fill rate, nothing is done.
     * <p>
     * Only data of open maps can be moved. For maps that are not open, the old
     * chunk is still referenced. Therefore, it is recommended to open all maps
     * before calling this method.
     *
     * @param fillRate the minimum percentage of live entries
     * @return if anything was written
     */
Try to reduce the file size by re-writing partially full chunks. Chunks
with a low number of live items are re-written. If the current fill rate
is higher than the target fill rate, nothing is done.

Only data of open maps can be moved. For maps that are not open, the old
chunk is still referenced. Therefore, it is recommended to open all maps
before calling this method.

@param fillRate the minimum percentage of live entries
@return if anything was written
Try to reduce the file size by re - writing partially full chunks . Chunks with a low number of live items are re - written . If the current fill rate is higher than the target fill rate nothing is done . Only data of open maps can be moved . For maps that are not open the old chunk is still referenced . Therefore it is recommended to open all maps before calling this method . @param fillRate the minimum percentage of live entries @return if anything was written
public synchronized boolean compact(int fillRate) {
        checkOpen();
        if (chunks.size() == 0) {
            return false;
        }
        long maxLengthSum = 0, maxLengthLiveSum = 0;
        for (Chunk c : chunks.values()) {
            maxLengthSum += c.maxLength;
            maxLengthLiveSum += c.maxLengthLive;
        }
        if (maxLengthSum <= 0) {
            maxLengthSum = 1;
        }
        int totalChunkFillRate = (int) (100 * maxLengthLiveSum / maxLengthSum);
        if (totalChunkFillRate > fillRate) {
            return false;
        }
        int averageMaxLength = (int) (maxLengthSum / chunks.size());
        long time = getTime();
        ArrayList<Chunk> old = New.arrayList();
        for (Chunk c : chunks.values()) {
            if (canOverwriteChunk(c, time)) {
                int age = lastChunkId - c.id + 1;
                c.collectPriority = c.getFillRate() / age;
                old.add(c);
            }
        }
        if (old.size() == 0) {
            return false;
        }
        Collections.sort(old, new Comparator<Chunk>() {
            @Override
            public int compare(Chunk o1, Chunk o2) {
                return new Integer(o1.collectPriority)
                        .compareTo(o2.collectPriority);
            }
        });
        long moved = 0;
        Chunk move = null;
        for (Chunk c : old) {
            if (move != null && moved + c.maxLengthLive > averageMaxLength) {
                break;
            }
            moved += c.maxLengthLive;
            move = c;
        }
        boolean remove = false;
        for (Iterator<Chunk> it = old.iterator(); it.hasNext();) {
            Chunk c = it.next();
            if (move == c) {
                remove = true;
            } else if (remove) {
                it.remove();
            }
        }
        for (Chunk c : old) {
            copyLive(c, old);
        }
        commitAndSave();
        return true;
    }
public synchronized boolean compact ( int fillRate ) { checkOpen ( ) ; if ( chunks . size ( ) == 0 ) { return false ; } long maxLengthSum = 0 , maxLengthLiveSum = 0 ; for ( Chunk c : chunks . values ( ) ) { maxLengthSum += c . maxLength ; maxLengthLiveSum += c . maxLengthLive ; } if ( maxLengthSum <= 0 ) { maxLengthSum = 1 ; } int totalChunkFillRate = ( int ) ( 100 * maxLengthLiveSum / maxLengthSum ) ; if ( totalChunkFillRate > fillRate ) { return false ; } int averageMaxLength = ( int ) ( maxLengthSum / chunks . size ( ) ) ; long time = getTime ( ) ; ArrayList < Chunk > old = New . arrayList ( ) ; for ( Chunk c : chunks . values ( ) ) { if ( canOverwriteChunk ( c , time ) ) { int age = lastChunkId - c . id + 1 ; c . collectPriority = c . getFillRate ( ) / age ; old . add ( c ) ; } } if ( old . size ( ) == 0 ) { return false ; } Collections . sort ( old , new Comparator < Chunk > ( ) { @ Override public int compare ( Chunk o1 , Chunk o2 ) { return new Integer ( o1 . collectPriority ) . compareTo ( o2 . collectPriority ) ; } } ) ; long moved = 0 ; Chunk move = null ; for ( Chunk c : old ) { if ( move != null && moved + c . maxLengthLive > averageMaxLength ) { break ; } moved += c . maxLengthLive ; move = c ; } boolean remove = false ; for ( Iterator < Chunk > it = old . iterator ( ) ; it . hasNext ( ) ; ) { Chunk c = it . next ( ) ; if ( move == c ) { remove = true ; } else if ( remove ) { it . remove ( ) ; } } for ( Chunk c : old ) { copyLive ( c , old ) ; } commitAndSave ( ) ; return true ; }
Try to reduce the file size by re-writing partially full chunks.
Try to reduce the file size by re - writing partially full chunks .
// nothing to do // avoid division by 0 // the fill rate of all chunks combined // calculate the average max length // the 'old' list contains the chunks we want to free up // sort the list, so the first entry should be collected first // find out up to were in the old list we need to move // try to move one (average sized) chunk // remove the chunks we want to keep from this list // iterate over all the pages in the old pages