All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sleepycat.je.rep.util.ldiff.BlockBag Maven / Gradle / Ivy

The newest version!
/*-
 * Copyright (C) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle Berkeley
 * DB Java Edition made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle Berkeley DB Java Edition for a copy of the
 * license and additional information.
 */

package com.sleepycat.je.rep.util.ldiff;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/**
 * A bag of Blocks used during the LDiff process. Blocks are accessed by their
 * checksum; when checksums collide, blocks are returned in insertion order.
 */
public class BlockBag implements Iterable {
    /* Map checksums to the corresponding block's index in blocks. */
    private final HashMap> chksums;
    /* Maintain the list of blocks in insertion order. */
    private final List blocks;

    /*
     * The index in blocks of the first block that has not yet been removed.
     * Items in blocks prior to blockIndex have been deleted from the bag.
     */
    private int blockIndex;

    /**
     * Instantiate a new BlockBag object.
     */
    public BlockBag() {
        blockIndex = 0;
        blocks = new ArrayList();
        chksums = new HashMap>();
    }

    /**
     * Adds a new Block to the bag.
     *
     * @param b The Block to be added.
     */
    public void add(Block b) {
        final Long chksum = b.getRollingChksum();
        final Integer indx = blocks.size();
        blocks.add(b);
        List indices = chksums.get(chksum);
        if (indices == null) {
            indices = new ArrayList();
        }
        indices.add(indx);
        chksums.put(chksum, indices);
    }

    /**
     * Returns all Blocks in the bag with a given checksum.
     *
     * @param chksum The checksum to match
     * @return A List of blocks with the given checksum, in insertion order, or
     * null if no matching blocks were found.
     */
    public List get(long chksum) {
        List indices;
        List ret;

        ret = new ArrayList();
        indices = chksums.get(new Long(chksum));
        if (indices == null) {
            return null;
        }
        for (Integer indx : indices) {
            int i = indx.intValue();
            if (i >= blockIndex)
                ret.add(blocks.get(i));
        }

        if (ret.size() == 0) {
            return null;
        }
        return ret;
    }

    /**
     * Returns an iterator over the blocks in the bag, in insertion order.
     *
     * @return an iterator over the blocks in the bag, in insertion order.
     */
    @Override
    public Iterator iterator() {
        return new BagIterator();
    }

    /**
     * Removes the given Block, plus any blocks inserted previous to the given
     * Block.
     *
     * @param b The Block to remove.
     * @return A List of all unmatched blocks, or null
     */
    public List remove(Block b) {
        final int startIndex = blockIndex;
        while (blockIndex < blocks.size()) {
            Block b2 = blocks.get(blockIndex);
            blockIndex++;
            if (b == b2) {
                break;
            }
        }

        return (blockIndex - startIndex <= 1) ? null : blocks.subList(
                startIndex, blockIndex - 1);
    }

    /**
     * Removes all blocks from the bag.
     *
     * @return A list of all blocks removed, or null if the bag is already
     * empty.
     */
    public List removeAll() {
        List ret;

        ret = new ArrayList();
        while (blockIndex < blocks.size()) {
            Block b = blocks.get(blockIndex);
            blockIndex++;
            ret.add(b);
        }

        if (ret.size() == 0) {
            return null;
        }
        return ret;
    }

    public int getBlockIndex() {
        return blockIndex;
    }

    public Block getBlock() {
        return blocks.get(blockIndex);
    }

    /**
     * Returns the number of blocks in this bag.
     *
     * @return the number of blocks in the bag
     */
    public int size() {
        return blocks.size() - blockIndex;
    }

    private class BagIterator implements Iterator {
        private int offset;

        BagIterator() {
            offset = 0;
        }

        @Override
        public boolean hasNext() {
            return (offset + blockIndex < blocks.size());
        }

        @Override
        public void remove() {
            BlockBag.this.remove(blocks.get(blockIndex));
        }

        @Override
        public Block next() {
            return blocks.get(blockIndex + offset++);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy