Package com.sleepycat.je.log.entry

Source Code of com.sleepycat.je.log.entry.NameLNLogEntry

/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002, 2011 Oracle and/or its affiliates.  All rights reserved.
*
*/

package com.sleepycat.je.log.entry;

import java.nio.ByteBuffer;

import com.sleepycat.je.dbi.DatabaseId;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.dbi.ReplicatedDatabaseConfig;
import com.sleepycat.je.log.DbOpReplicationContext;
import com.sleepycat.je.log.LogEntryHeader;
import com.sleepycat.je.log.LogEntryType;
import com.sleepycat.je.log.ReplicationContext;
import com.sleepycat.je.tree.NameLN;
import com.sleepycat.je.txn.Txn;

/**
* NameLNLogEntry contains all the regular LNLogEntry fields and additional
* information about the database operation which instigated the logging of
* this NameLN. This additional information is used to support replication of
* database operations in a replication group.
*
* Database operations pose a special problem for replication because unlike
* data record put and get calls, they can result in multiple log entries that
* are not all members of a single transaction.  Create and truncate are the
* problem operations because they end up logging new MapLNs, and our
* implementation does not treat MapLNs as transactional.  Database operations
* challenge two replication assumptions: (a) that all logical operations can
* be repeated on the client node based on the contents of a single log entry,
* and (b) that non-txnal log entries like MapLNs need not be replicated.
*
* Specifically, here's what is logged for database operations.
*
* create:
*
*  1. new NameLN_TX
*  2. new MapLN, which has the database config info.
*  3. txn commit of autocommit or user txn.
*
* rename:
*
*  1. deleted NameLN_TX
*  2. new NameLN_TX
*  3. txn commit from autocommit or user txn
*
* truncate:
*
*  1. new MapLN w/new id
*  2. modify the existing NameLN with new id (old database is deleted by
*     usual commit-time processing)
*  3. txn commit from autocommit or user txn
*
* delete
*
*  1. deleted NameLN_TX (old database gets deleted by usual commit-time
*     processing)
*  2. txn commit from autocommit or user txn
*
* Extra information is needed for create and truncate, which both log
* information within the MapLN. Rename and delete only log NameLNs, so they
* can be replicated on the client using the normal replication messages.  The
* extra fields which follow the usual LNLogEntry fields are:
*
* operationType - the type of database operation. In a single node system,
*                 this is local information implicit in the code path.
* databaseConfig (optional) - For creates, database configuration info
* databaseId (optional)- For truncates, the old db id, so we know which
*                        MapLN to delete.
*/
public class NameLNLogEntry extends LNLogEntry {

    /*
     * operationType, truncateOldDbId and replicatedCreateConfig are
     * logged as part of the entry.
     */
    private DbOperationType operationType;
    private DatabaseId truncateOldDbId;
    private ReplicatedDatabaseConfig replicatedCreateConfig;

    /**
     * Constructor to read an entry.
     */
    public NameLNLogEntry() {
        super(com.sleepycat.je.tree.NameLN.class);
    }

    /**
     * Constructor to write this entry.
     */
    public NameLNLogEntry(LogEntryType entryType,
                          NameLN nameLN,
                          DatabaseId dbId,
                          byte[] key,
                          long abortLsn,
                          boolean abortKnownDeleted,
                          Txn txn,
                          ReplicationContext repContext) {

        super(entryType, nameLN, dbId, key, abortLsn, abortKnownDeleted, txn);
        ReplicationContext operationContext = repContext;

        operationType = repContext.getDbOperationType();
        if (DbOperationType.isWriteConfigType(operationType)) {
            replicatedCreateConfig =
                ((DbOpReplicationContext) operationContext).getCreateConfig();
        }
       
        if (operationType == DbOperationType.TRUNCATE) {
            truncateOldDbId =
              ((DbOpReplicationContext) operationContext).getTruncateOldDbId();
        }
    }

    /**
     * Extends its super class to read in database operation information.
     * @see LNLogEntry#readEntry
     */
    @Override
    public void readEntry(EnvironmentImpl envImpl,
                          LogEntryHeader header,
                          ByteBuffer entryBuffer) {

        readBaseLNEntry(envImpl, header, entryBuffer,
                        false /*keyIsLastSerializedField*/);

        /*
         * The NameLNLogEntry was introduced in version 6. Before, a LNLogEntry
         * was used for NameLNs, and there is no extra information in the log
         * entry.
         */
        int version = header.getVersion();
        if (version >= 6) {
            operationType = DbOperationType.readTypeFromLog(entryBuffer,
                                                            version);
            if (DbOperationType.isWriteConfigType(operationType)) {
                replicatedCreateConfig = new ReplicatedDatabaseConfig();
                replicatedCreateConfig.readFromLog(entryBuffer, version);
            }
           
            if (operationType == DbOperationType.TRUNCATE) {
                truncateOldDbId = new DatabaseId();
                truncateOldDbId.readFromLog(entryBuffer, version);
            }
        } else {
            operationType = DbOperationType.NONE;
        }
    }

    /**
     * Extends its super class to dump database operation information.
     * @see LNLogEntry#dumpEntry
     */
    @Override
    public StringBuilder dumpEntry(StringBuilder sb, boolean verbose) {

        super.dumpEntry(sb, verbose);

        operationType.dumpLog(sb, verbose);
        if (replicatedCreateConfig != null ) {
            replicatedCreateConfig.dumpLog(sb, verbose);
        }
        if (truncateOldDbId != null) {
            truncateOldDbId.dumpLog(sb, verbose);
        }

        return sb;
    }

    /**
     * Extends its super class to add in database operation information.
     * @see LNLogEntry#getSize
     */
    @Override
    public int getSize() {
        int size = getBaseLNEntrySize(false /*keyIsLastSerializedField*/) +
                   operationType.getLogSize();

        if (DbOperationType.isWriteConfigType(operationType)) {
            size += replicatedCreateConfig.getLogSize();
        }

        if (operationType == DbOperationType.TRUNCATE) {
            size += truncateOldDbId.getLogSize();
        }
        return size;
    }

    /**
     * Extends its super class to add in database operation information.
     * @see LogEntry#writeToLog
     */
    @Override
    public void writeEntry(LogEntryHeader header, ByteBuffer destBuffer) {

        writeBaseLNEntry(header, destBuffer,
                         false /*keyIsLastSerializedField*/);

        operationType.writeToLog(destBuffer);
        if (DbOperationType.isWriteConfigType(operationType)) {
            replicatedCreateConfig.writeToLog(destBuffer);
        }
       
        if (operationType == DbOperationType.TRUNCATE) {
            truncateOldDbId.writeToLog(destBuffer);
        }
    }

    /**
     * @see LogEntry#logicalEquals
     */
    @Override
    public boolean logicalEquals(LogEntry other) {

        if (!super.logicalEquals(other))
            return false;

        NameLNLogEntry otherEntry = (NameLNLogEntry) other;
        if (!operationType.logicalEquals(otherEntry.operationType)) {
            return false;
        }

        if ((truncateOldDbId != null) &&
            (!truncateOldDbId.logicalEquals(otherEntry.truncateOldDbId))) {
                return false;
        }

        if (replicatedCreateConfig != null) {
            if (!replicatedCreateConfig.logicalEquals
                (otherEntry.replicatedCreateConfig))
                return false;
        }
        return true;
    }

    /**
     * @return the operationType
     */
    public DbOperationType getOperationType() {
        return operationType;
    }

    /**
     * @return the replicatedCreateConfig
     */
    public ReplicatedDatabaseConfig getReplicatedCreateConfig() {
        return replicatedCreateConfig;
    }

    /**
     * @return the truncateOldDbId
     */
    public DatabaseId getTruncateOldDbId() {
        return truncateOldDbId;
    }

    /**
     * @see LogEntry#dumpRep
     */
    public void dumpRep(StringBuilder sb) {
        super.dumpRep(sb);
        sb.append(" dbop=").append(operationType);
    }
}
TOP

Related Classes of com.sleepycat.je.log.entry.NameLNLogEntry

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.