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

com.sleepycat.je.rep.vlsn.GhostBucket 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.vlsn;

import com.sleepycat.bind.tuple.TupleInput;
import com.sleepycat.bind.tuple.TupleOutput;
import com.sleepycat.je.EnvironmentFailureException;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.utilint.DbLsn;
import com.sleepycat.je.utilint.VLSN;

/**
 * A ghost bucket stands in as a placeholder for a set of vlsns that are 
 * unknown. This kind of bucket can only be present at the very beginning of 
 * the vlsn range. 
 *
 * This fulfills an edge case that can arise when vlsns are inserted out of 
 * order, and log cleaner truncation lops off the leading edge of the index. 
 * For example, suppose vlsns were inserted in this order:

 * vlsnIndex.put(vlsn=2, lsn=1/2)
 * vlsnIndex.put(vlsn=1, lsn=1/0)
 * vlsnIndex.put(vlsn=3, lsn=1/3)
 * ...
 * vlsnIndex.put(vlsn=5, lsn=2/9)
 * vlsnIndex.put(vlsn=4, lsn=2/0)
 * vlsnIndex.put(vlsn=6, lsn=2/10)
 * ..
 * This results in an index that has two buckets. Bucket 1 = {vlsn 2,3} and
 * bucket 2 = {vlsn 5,6}. If we log clean file 1, we will truncate log at vlsn
 * 3, and the new range will be vlsn 4-> vlsn 6. But the beginning and end of
 * each range needs to have a valid bucket, and there is no bucket to represent
 * vlsn 4. A GhostBucket is added to the head of the bucket set.
 */
class GhostBucket extends VLSNBucket {
    private long firstPossibleLsn;
    private long lastPossibleLsn;
    
    GhostBucket(VLSN ghostVLSN,
                long firstPossibleLsn,
                long lastPossibleLsn) {
        /* 
         * Use ghostVLSN for the firstVLSN, which will make the own(),
         * getFirst, getLast() methods work.
         */
        super(DbLsn.getFileNumber(firstPossibleLsn), // fileNumber
              0, // stride
              1, // maxMappings
              1, // maxDistance,
              ghostVLSN); // firstVLSN
        this.firstPossibleLsn = firstPossibleLsn;
        this.lastPossibleLsn = lastPossibleLsn;
        dirty = true;
    }

    /**
     * Ideally, this would be a constructor, but we have to read several
     * items off the tuple input first before calling super();
     */
    static GhostBucket makeNewInstance(TupleInput ti) {
        VLSN ghostVLSN = new VLSN(ti.readPackedLong());
        long firstLsn = ti.readPackedLong();
        long lastLsn = ti.readPackedLong();
        return new GhostBucket(ghostVLSN, firstLsn, lastLsn);
    }

    @Override
    boolean isGhost() {
        return true;
    }

    @Override
    void writeToTupleOutput(TupleOutput to) {
        to.writePackedLong(firstVLSN.getSequence());
        to.writePackedLong(firstPossibleLsn);
        to.writePackedLong(lastPossibleLsn);
    }

    /**
     * Return a lsn as a starting point for a backward scan.
     */
    @Override
    public synchronized long getGTELsn(VLSN vlsn) { 
        return lastPossibleLsn;
    }

    /**
     * Return a lsn as a starting point for a forward scan.
     */
    @Override
    synchronized long getLTELsn(VLSN vlsn) { 
        return firstPossibleLsn;
    }

    /**
     * There is no mapping for this VLSN, so always return NULL_LSN.
     */
    @Override
    public synchronized long getLsn(VLSN vlsn) { 
        return DbLsn.NULL_LSN;            
    }

    /**
     * Return a file number that is less or equal to the first mapped vlsn,
     * for use in determining the CBVLSN.
     */
    @Override 
    long getLTEFileNumber() {
        return DbLsn.getFileNumber(firstPossibleLsn);
    }

    @Override
    long getGTEFileNumber() {
        return DbLsn.getFileNumber(lastPossibleLsn);
    }

    @Override
    synchronized boolean put(VLSN vlsn, long lsn) {
        throw EnvironmentFailureException.unexpectedState
            ("Shouldn't be called");
    }
          
    @Override
    VLSNBucket removeFromHead(EnvironmentImpl envImpl, 
                                  VLSN lastDuplicate) {
        throw EnvironmentFailureException.unexpectedState
            ("Shouldn't be called, only used in recovery merging.");
    }

    @Override
    void removeFromTail(VLSN startOfDelete, long prevLsn) {
    
        throw EnvironmentFailureException.unexpectedState
            ("Shouldn't be called");
    }

    @Override
    int getNumOffsets() {
        return 0;
    }

    @Override 
    public String toString() {
        StringBuilder sb = new StringBuilder("");
        return sb.toString();
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy