Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*-
   * See the file LICENSE for redistribution information.
   *
   * Copyright (c) 2002, 2013 Oracle and/or its affiliates.  All rights reserved.
   *
   */
  
  package com.sleepycat.je.rep.impl.node;
  
 import static com.sleepycat.je.rep.impl.RepParams.REP_STREAM_TIMEOUT;
 import static com.sleepycat.je.utilint.VLSN.NULL_VLSN;
 
 
Represents this node's view of the global CBVLSN. Each node has its own view of the global CBVLSN, based upon its local replicated copy of the rep group db. There is a single instance of the GlobalCBVLSN and it exists for the lifetime of the RepNode. A global CBVLSN is a per-environment value, and is safeguarded from decreasing during the lifetime of a single RepImpl. Because nodes crash and re-sync, and new nodes join, it's possible that the persisted local cbvlsns can decrease, and drag the global cbvlsn value down, but those decreases are ignored during the lifetime of the global CBVLSN instance. The global CBVLSN is used by: 1. The Cleaner 2. The Feeder which only serves log records in the interval: [GlobalCBVLSN .. VLSNRange.last] 3. The Replica which uses the interval [GlobalCBVLSN .. VLSNRange.last] at syncup time.
 
 class GlobalCBVLSN {
 
     private final RepImpl repImpl;
     private final Logger logger;
     private final long streamTimeoutMs;
 
     /*
      * ActiveSyncups serves to stop updates to the group CBVLSN when
      * replica/master syncups are in progress. GroupCBVLSN will not be updated
      * if activeSyncups > 0. ActiveSyncups and groupCBVLSN can only be updated
      * when synchronized.
      */
     private volatile VLSN groupCBVLSN = .;
     private int activeSyncups = 0;
 
     GlobalCBVLSN(RepNode repNode) {
         this. = repNode.getRepImpl();
          =
          = LoggerUtils.getLogger(getClass());
     }
 
     VLSN getCBVLSN() {
         return ;
     }
 
     /* ActiveSyncups gates the update of the global CBVLSN */
     synchronized void syncupStarted() {
         ++;
         LoggerUtils.finest
             ("activeSyncups = " + );
     }
 
     /* ActiveSyncups gates the update of the global CBVLSN */
     synchronized void syncupEnded() {
         --;
         LoggerUtils.finest
             ("activeSyncups = " + );
     }

    
Returns the file number that forms a barrier for the cleaner's file deletion activities. Files with numbers >= this file number cannot be by the cleaner without disrupting the replication stream.

Returns:
the file number that's the barrier for cleaner file deletion
Throws:
com.sleepycat.je.DatabaseException
 
     long getCleanerBarrierFile()
         throws DatabaseException {
         if (.isNull()) {
             return 0;
         }
 
    }

    
Recalculate the cached, global CBVLSN. The globalCBVLSN is computed as the minimum of CBVLSNs after discarding CBVLSNs that are obsolete. A CBVLSN is considered obsolete, if it has not been updated within a configurable time interval relative to the time that the most recent CBVLSN was updated. Note that the read of GroupInfo is not protected, and that groupInfo could be changing. That's okay, because we guarantee that none of the local CBVLSNs can be set to be LT globalCBVLSN. If a local CBVLSN is written, and we miss it, it only means that this recalcuation of global CBVLSN is too pessimistic -- it's too low. The low range of the VLSNIndex may be LTE the GlobalCBVLSN. The VLSNIndex is only truncated when a log file is actually deleted. This separates the cost of the Global CBVLSN recalculation from the cost of the VLSNIndex truncation, sinc the latter may require I/O. This also makes it easier and cheaper to obey the rule that the VLSNIndex truncation only occur on bucket boundaries.
    void recalculate(RepGroupImpl groupInfo) {
        /* Find the time the highest CBVLSN was computed. */
        VLSN maxCBVLSN = ;
        long latestBarrierTime = 0;
        for (RepNodeImpl node : groupInfo.getElectableNodes()) {
            BarrierState nodeBarrier = node.getBarrierState();
            VLSN cbvlsn = nodeBarrier.getLastCBVLSN();
            /*
             * Count all nodes, including those that are in the middle of
             * syncup and have not established their low point when finding the
             * max time.
             */
            final long nodeBarrierTime = nodeBarrier.getBarrierTime();
            if (maxCBVLSN.compareTo(cbvlsn) <= 0) {
                /*
                 * Use min, since it represents the real change when they are
                 * equal.
                 */
                latestBarrierTime = cbvlsn.equals(maxCBVLSN) ?
                    Math.min(nodeBarrierTimelatestBarrierTime) :
                    nodeBarrierTime;
                maxCBVLSN = cbvlsn;
            }
        }
        if (latestBarrierTime == 0) {
            /* No cbvlsns entered yet, don't bother to recalculate. */
            return;
        }
        if (maxCBVLSN.isNull()) {
            /* No cbvlsns entered yet, don't bother to recalculate. */
            return;
        }
        /*
         * Now find the min CBVLSN that has not been timed out. This may mean
         * that the min CBVLSN == NULL_VLSN, for nodes that have not yet
         * finished syncup.
         */
        VLSN newGroupCBVLSN = maxCBVLSN;
        for (RepNodeImpl node : groupInfo.getElectableNodes()) {
            BarrierState nodeBarrier = node.getBarrierState();
            VLSN nodeCBVLSN = nodeBarrier.getLastCBVLSN();
            if (((latestBarrierTime - nodeBarrier.getBarrierTime()) <=
                 ) &&
                (newGroupCBVLSN.compareTo(nodeCBVLSN) > 0)) {
                newGroupCBVLSN = nodeCBVLSN;
            }
        }
        updateGroupCBVLSN(groupInfonewGroupCBVLSN);
    }
    /*
     * Update the group CBVLSN, but only if the newGroupCBVLSN is more recent
     * This is to ensure that the group CBVLSN can only advance during the
     * lifetime of this instance.
     */
    private void updateGroupCBVLSN(RepGroupImpl groupInfo,
                                   VLSN newGroupCBVLSN) {
        boolean changed = false;
        int numGatingSyncups = 0;
        String cbvlsnLoweredMessage = null;
        VLSN oldCBVLSN = .;
        synchronized(this) {
            /*
             * Be sure not to do anything expensive in this synchronized
             * section, such as logging.
             */
            if (newGroupCBVLSN.compareTo() > 0) {
                if ( == 0) {
                    VLSNRange currentRange = .getVLSNIndex().getRange();
                    if (!currentRange.contains(newGroupCBVLSN) &&
                        .isLoggable(.)) {
                        cbvlsnLoweredMessage =
                            "GroupCBVLSN: " + newGroupCBVLSN +
                            " is outside VLSN range: " + currentRange +
                            " Current group:" + groupInfo;
                    } else {
                        oldCBVLSN = ;
                         = newGroupCBVLSN;
                        changed = true;
                    }
                } else {
                    /*
                     * Any active syncups prohibit the global cbvlsn update.
                     * Save this fact for logging outside the critical section.
                     */
                    numGatingSyncups = ;
                }
            }
        }
        if (.isLoggable(.)) {
            if (cbvlsnLoweredMessage != null) {
                LoggerUtils.fine(cbvlsnLoweredMessage);
            }
            if (changed) {
                LoggerUtils.fine(,
                                 "Global CBVLSN changed from " + oldCBVLSN +
                                 " to " + newGroupCBVLSN);
            }
            if (numGatingSyncups > 0) {
                LoggerUtils.fine(,
                                 "Global CBVLSN update gated by " +
                                 numGatingSyncups + " syncups");
            }
        }
    }
New to GrepCode? Check out our FAQ X