1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002, 2014 Oracle and/or its affiliates.  All rights reserved.
5  *
6  */
7 
8 package com.sleepycat.je.log.entry;
9 
10 import java.nio.ByteBuffer;
11 
12 import com.sleepycat.je.log.LogEntryType;
13 
14 /**
15  * A sub-interface of {@link LogEntry} that must be implemented by all log
16  * entries that can be replicated.  Replicable log entries are all those
17  * entries for which the associated {@link LogEntryType}'s {@link
18  * LogEntryType#isReplicationPossible} method returns {@code true}.  These are
19  * the log entries that can be included in the replication stream distributed
20  * from feeders to replicas during replication.  See [#22336].
21  *
22  * <p>Starting with the release using log version 9, as specified by {@link
23  * LogEntryType#LOG_VERSION_REPLICATE_PREVIOUS}, all replicable log entries
24  * need to support writing themselves in the previous log format, to support
25  * replication during an upgrade when the master is replicated first.  Any
26  * loggable objects that they reference should also implement {@link
27  * VersionedWriteLoggable} for the same reason.  Since upgrades are only
28  * supported from one version to the next version that introduced an
29  * incompatible change, log entries are only required to support writing
30  * themselves in the immediately previous log file format.
31  *
32  * <p>The {@link #getLastFormatChange} method identifies the log version for
33  * which the entry's log format has most recently changed.  This information is
34  * used to determine if the current log format is compatible with a
35  * non-upgraded replica.
36  *
37  * <p>The {@link #getSize(int)} method overloading is used when creating the
38  * buffer that will be used to transmit the log entry data in the earlier
39  * format.
40  *
41  * <p>The {@link #writeEntry(ByteBuffer, int)} method overloading is used to
42  * convert the in-memory format of the log entry into the log data in the
43  * earlier format.
44  *
45  * <p>To simplify the implementation of writing log entries in multiple log
46  * version formats, a log entry that needs to be written in a previous format
47  * will first be read into its in-memory format in the current version, and
48  * then written from there to the previous format.  This way, only one format
49  * conversion needs to be supported.  Although implementations could remove the
50  * conversion as soon as the next incompatible software version is introduced,
51  * as a practical matter it makes more sense to remove a conversion from a
52  * given class only when the next format change is made to that class.
53  */
54 public interface ReplicableLogEntry extends LogEntry {
55 
56     /**
57      * Returns the log version of the most recent format change for this log
58      * entry.
59      *
60      * @return the log version of the most recent format change
61      */
getLastFormatChange()62     int getLastFormatChange();
63 
64     /**
65      * Returns the number of bytes needed to store this entry in the format for
66      * the specified log version.  Only the current and immediately previous
67      * log versions need to be supported, and the previous log version only
68      * needs to be supported for log entries with format changes made in {@link
69      * LogEntryType#LOG_VERSION_REPLICATE_PREVIOUS} or greater.
70      *
71      * @param logVersion the log version
72      * @return the number of bytes to store this entry for the log version
73      * @throws IllegalArgumentException if the log version is not supported
74      */
getSize(int logVersion)75     int getSize(int logVersion);
76 
77     /**
78      * Serializes this object into the specified buffer in the format for the
79      * specified log version.  Only the current and immediately previous log
80      * versions need to be supported, and the previous log version only
81      * needs to be supported for log entries with format changes made in {@link
82      * LogEntryType#LOG_VERSION_REPLICATE_PREVIOUS} or greater.
83      *
84      * @param logBuffer the destination buffer
85      * @param logVersion the log version
86      * @throws IllegalArgumentException if the log version is not supported
87      */
writeEntry(ByteBuffer logBuffer, int logVersion)88     void writeEntry(ByteBuffer logBuffer, int logVersion);
89 }
90