jdk/src/share/classes/sun/rmi/log/ReliableLog.java
author khazra
Fri, 02 Mar 2012 13:48:43 -0800
changeset 12040 558b0e0d5910
parent 9502 de183d393b77
child 14342 8435a30053c1
permissions -rw-r--r--
7146763: Warnings cleanup in the sun.rmi and related packages Summary: Cleanup warnings and use jkd7 features in sun.rmi.* Reviewed-by: smarks, chegar, forax, dmocek
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
     2
 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 715
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.rmi.log;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.lang.reflect.Constructor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.rmi.server.RMIClassLoader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.security.AccessController;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.security.PrivilegedAction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import sun.security.action.GetBooleanAction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import sun.security.action.GetPropertyAction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * This class is a simple implementation of a reliable Log.  The
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * client of a ReliableLog must provide a set of callbacks (via a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * LogHandler) that enables a ReliableLog to read and write
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * checkpoints and log records.  This implementation ensures that the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * current value of the data stored (via a ReliableLog) is recoverable
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * after a system crash. <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * The secondary storage strategy is to record values in files using a
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * representation of the caller's choosing.  Two sorts of files are
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * kept: snapshots and logs.  At any instant, one snapshot is current.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * The log consists of a sequence of updates that have occurred since
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * the current snapshot was taken.  The current stable state is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * value of the snapshot, as modified by the sequence of updates in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * the log.  From time to time, the client of a ReliableLog instructs
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * the package to make a new snapshot and clear the log.  A ReliableLog
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * arranges disk writes such that updates are stable (as long as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * changes are force-written to disk) and atomic : no update is lost,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * and each update either is recorded completely in the log or not at
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * all.  Making a new snapshot is also atomic. <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * Normal use for maintaining the recoverable store is as follows: The
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * client maintains the relevant data structure in virtual memory.  As
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * updates happen to the structure, the client informs the ReliableLog
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * (all it "log") by calling log.update.  Periodically, the client
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * calls log.snapshot to provide the current value of the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * structure.  On restart, the client calls log.recover to obtain the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * latest snapshot and the following sequences of updates; the client
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * applies the updates to the snapshot to obtain the state that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * existed before the crash. <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * The current logfile format is: <ol>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * <li> a format version number (two 4-octet integers, major and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * minor), followed by
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * <li> a sequence of log records.  Each log record contains, in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * order, <ol>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * <li> a 4-octet integer representing the length of the following log
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * data,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * <li> the log data (variable length). </ol> </ol> <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * @see LogHandler
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * @author Ann Wollrath
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
public class ReliableLog {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    public final static int PreferredMajorVersion = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    public final static int PreferredMinorVersion = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    // sun.rmi.log.debug=false
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    private boolean Debug = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    private static String snapshotPrefix = "Snapshot.";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    private static String logfilePrefix = "Logfile.";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    private static String versionFile = "Version_Number";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    private static String newVersionFile = "New_Version_Number";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    private static int    intBytes = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    private static long   diskPageSize = 512;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    private File dir;                   // base directory
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    private int version = 0;            // current snapshot and log version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    private String logName = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    private LogFile log = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    private long snapshotBytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    private long logBytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    private int logEntries = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    private long lastSnapshot = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    private long lastLog = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    //private long padBoundary = intBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    private LogHandler handler;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    private final byte[] intBuf = new byte[4];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    // format version numbers read from/written to this.log
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    private int majorFormatVersion = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    private int minorFormatVersion = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * Constructor for the log file.  If the system property
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * sun.rmi.log.class is non-null and the class specified by this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * property a) can be loaded, b) is a subclass of LogFile, and c) has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * public two-arg constructor (String, String), ReliableLog uses the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * constructor to construct the LogFile.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    private static final Constructor<? extends LogFile>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        logClassConstructor = getLogClassConstructor();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * Creates a ReliableLog to handle checkpoints and logging in a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * stable storage directory.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     * @param dirPath path to the stable storage directory
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     * @param logCl the closure object containing callbacks for logging and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
     * recovery
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
     * @param pad ignored
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     * @exception IOException If a directory creation error has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     * occurred or if initialSnapshot callback raises an exception or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * if an exception occurs during invocation of the handler's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     * snapshot method or if other IOException occurs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    public ReliableLog(String dirPath,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                     LogHandler handler,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                     boolean pad)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
        super();
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   143
        this.Debug = AccessController.doPrivileged(
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   144
            new GetBooleanAction("sun.rmi.log.debug")).booleanValue();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        dir = new File(dirPath);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        if (!(dir.exists() && dir.isDirectory())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            // create directory
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            if (!dir.mkdir()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                throw new IOException("could not create directory for log: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                                      dirPath);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        //padBoundary = (pad ? diskPageSize : intBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        this.handler = handler;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        lastSnapshot = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        lastLog = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        getVersion();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        if (version == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
                snapshot(handler.initialSnapshot());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
                throw new IOException("initial snapshot failed with " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                                      "exception: " + e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * Creates a ReliableLog to handle checkpoints and logging in a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * stable storage directory.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     * @param dirPath path to the stable storage directory
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     * @param logCl the closure object containing callbacks for logging and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     * recovery
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
     * @exception IOException If a directory creation error has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     * occurred or if initialSnapshot callback raises an exception
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    public ReliableLog(String dirPath,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
                     LogHandler handler)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        this(dirPath, handler, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    /* public methods */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     * Returns an object which is the value recorded in the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     * snapshot.  This snapshot is recovered by calling the client
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     * supplied callback "recover" and then subsequently invoking
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     * the "readUpdate" callback to apply any logged updates to the state.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     * @exception IOException If recovery fails due to serious log
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * corruption, read update failure, or if an exception occurs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     * during the recover callback
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    public synchronized Object recover()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        if (Debug)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            System.err.println("log.debug: recover()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        if (version == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        Object snapshot;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        String fname = versionName(snapshotPrefix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        File snapshotFile = new File(fname);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        InputStream in =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                new BufferedInputStream(new FileInputStream(snapshotFile));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        if (Debug)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            System.err.println("log.debug: recovering from " + fname);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
                snapshot = handler.recover(in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
            } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                if (Debug)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                    System.err.println("log.debug: recovery failed: " + e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                throw new IOException("log recover failed with " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                                      "exception: " + e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            snapshotBytes = snapshotFile.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            in.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        return recoverUpdates(snapshot);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     * Records this update in the log file (does not force update to disk).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     * The update is recorded by calling the client's "writeUpdate" callback.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     * This method must not be called until this log's recover method has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     * been invoked (and completed).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     * @param value the object representing the update
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     * @exception IOException If an exception occurred during a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     * writeUpdate callback or if other I/O error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    public synchronized void update(Object value) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        update(value, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * Records this update in the log file.  The update is recorded by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     * calling the client's writeUpdate callback.  This method must not be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     * called until this log's recover method has been invoked
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     * (and completed).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     * @param value the object representing the update
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     * @param forceToDisk ignored; changes are always forced to disk
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * @exception IOException If force-write to log failed or an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * exception occurred during the writeUpdate callback or if other
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     * I/O error occurs while updating the log.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    public synchronized void update(Object value, boolean forceToDisk)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        // avoid accessing a null log field.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        if (log == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            throw new IOException("log is inaccessible, " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                "it may have been corrupted or closed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
         * If the entry length field spans a sector boundary, write
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
         * the high order bit of the entry length, otherwise write zero for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
         * the entry length.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        long entryStart = log.getFilePointer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        boolean spansBoundary = log.checkSpansBoundary(entryStart);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        writeInt(log, spansBoundary? 1<<31 : 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
         * Write update, and sync.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            handler.writeUpdate(new LogOutputStream(log), value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
            throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            throw (IOException)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                new IOException("write update failed").initCause(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        log.sync();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        long entryEnd = log.getFilePointer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        int updateLen = (int) ((entryEnd - entryStart) - intBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        log.seek(entryStart);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        if (spansBoundary) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
             * If length field spans a sector boundary, then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
             * the next two steps are required (see 4652922):
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
             * 1) Write actual length with high order bit set; sync.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
             * 2) Then clear high order bit of length; sync.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            writeInt(log, updateLen | 1<<31);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            log.sync();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            log.seek(entryStart);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            log.writeByte(updateLen >> 24);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            log.sync();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
             * Write actual length; sync.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            writeInt(log, updateLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            log.sync();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        log.seek(entryEnd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        logBytes = entryEnd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        lastLog = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        logEntries++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * Returns the constructor for the log file if the system property
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * sun.rmi.log.class is non-null and the class specified by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     * property a) can be loaded, b) is a subclass of LogFile, and c) has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     * public two-arg constructor (String, String); otherwise returns null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
    private static Constructor<? extends LogFile>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        getLogClassConstructor() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   336
        String logClassName = AccessController.doPrivileged(
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   337
            new GetPropertyAction("sun.rmi.log.class"));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        if (logClassName != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                ClassLoader loader =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                    AccessController.doPrivileged(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                        new PrivilegedAction<ClassLoader>() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                            public ClassLoader run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                               return ClassLoader.getSystemClassLoader();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                        });
12040
558b0e0d5910 7146763: Warnings cleanup in the sun.rmi and related packages
khazra
parents: 9502
diff changeset
   347
                Class<? extends LogFile> cl =
558b0e0d5910 7146763: Warnings cleanup in the sun.rmi and related packages
khazra
parents: 9502
diff changeset
   348
                    loader.loadClass(logClassName).asSubclass(LogFile.class);
558b0e0d5910 7146763: Warnings cleanup in the sun.rmi and related packages
khazra
parents: 9502
diff changeset
   349
                return cl.getConstructor(String.class, String.class);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
            } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                System.err.println("Exception occurred:");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                e.printStackTrace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     * Records this value as the current snapshot by invoking the client
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     * supplied "snapshot" callback and then empties the log.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     * @param value the object representing the new snapshot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     * @exception IOException If an exception occurred during the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     * snapshot callback or if other I/O error has occurred during the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     * snapshot process
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    public synchronized void snapshot(Object value)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        int oldVersion = version;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        incrVersion();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        String fname = versionName(snapshotPrefix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
        File snapshotFile = new File(fname);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        FileOutputStream out = new FileOutputStream(snapshotFile);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
                handler.snapshot(out, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            } catch (Exception e) {
9502
de183d393b77 6896297: (rmi) fix ConcurrentModificationException causing TCK failure
smarks
parents: 5506
diff changeset
   382
                throw new IOException("snapshot failed", e);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            lastSnapshot = System.currentTimeMillis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
            out.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            snapshotBytes = snapshotFile.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        openLogFile(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        writeVersionFile(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        commitToNewVersion();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        deleteSnapshot(oldVersion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        deleteLogFile(oldVersion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     * Close the stable storage directory in an orderly manner.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     * @exception IOException If an I/O error occurs when the log is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
     * closed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    public synchronized void close() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        if (log == null) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
            log.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
            log = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
     * Returns the size of the snapshot file in bytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    public long snapshotSize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        return snapshotBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
     * Returns the size of the log file in bytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    public long logSize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        return logBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    /* private methods */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
     * Write an int value in single write operation.  This method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
     * assumes that the caller is synchronized on the log file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
     * @param out output stream
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
     * @param val int value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
     * @throws IOException if any other I/O error occurs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
    private void writeInt(DataOutput out, int val)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        intBuf[0] = (byte) (val >> 24);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        intBuf[1] = (byte) (val >> 16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        intBuf[2] = (byte) (val >> 8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        intBuf[3] = (byte) val;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        out.write(intBuf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
     * Generates a filename prepended with the stable storage directory path.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     * @param name the leaf name of the file
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
    private String fName(String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        return dir.getPath() + File.separator + name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
     * Generates a version 0 filename prepended with the stable storage
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
     * directory path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     * @param name version file name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
    private String versionName(String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        return versionName(name, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
     * Generates a version filename prepended with the stable storage
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
     * directory path with the version number as a suffix.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
     * @param name version file name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
     * @thisversion a version number
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    private String versionName(String prefix, int ver) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        ver = (ver == 0) ? version : ver;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        return fName(prefix) + String.valueOf(ver);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
     * Increments the directory version number.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
    private void incrVersion() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        do { version++; } while (version==0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
     * Delete a file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
     * @param name the name of the file
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
     * @exception IOException If new version file couldn't be removed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
    private void deleteFile(String name) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        File f = new File(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        if (!f.delete())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
            throw new IOException("couldn't remove file: " + name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
     * Removes the new version number file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
     * @exception IOException If an I/O error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
    private void deleteNewVersionFile() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        deleteFile(fName(newVersionFile));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
     * Removes the snapshot file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
     * @param ver the version to remove
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
     * @exception IOException If an I/O error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
    private void deleteSnapshot(int ver) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        if (ver == 0) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        deleteFile(versionName(snapshotPrefix, ver));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
     * Removes the log file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
     * @param ver the version to remove
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
     * @exception IOException If an I/O error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    private void deleteLogFile(int ver) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        if (ver == 0) return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
        deleteFile(versionName(logfilePrefix, ver));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
     * Opens the log file in read/write mode.  If file does not exist, it is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
     * created.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
     * @param truncate if true and file exists, file is truncated to zero
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
     * length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
     * @exception IOException If an I/O error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
    private void openLogFile(boolean truncate) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        } catch (IOException e) { /* assume this is okay */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
        logName = versionName(logfilePrefix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            log = (logClassConstructor == null ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                   new LogFile(logName, "rw") :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                   logClassConstructor.newInstance(logName, "rw"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            throw (IOException) new IOException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                "unable to construct LogFile instance").initCause(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        if (truncate) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            initializeLogFile();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
     * Creates a new log file, truncated and initialized with the format
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
     * version number preferred by this implementation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
     * <p>Environment: inited, synchronized
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
     * <p>Precondition: valid: log, log contains nothing useful
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
     * <p>Postcondition: if successful, log is initialised with the format
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
     * version number (Preferred{Major,Minor}Version), and logBytes is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     * set to the resulting size of the updatelog, and logEntries is set to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
     * zero.  Otherwise, log is in an indeterminate state, and logBytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
     * is unchanged, and logEntries is unchanged.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
     * @exception IOException If an I/O error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    private void initializeLogFile()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
        log.setLength(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
        majorFormatVersion = PreferredMajorVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
        writeInt(log, PreferredMajorVersion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        minorFormatVersion = PreferredMinorVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
        writeInt(log, PreferredMinorVersion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
        logBytes = intBytes * 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        logEntries = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
     * Writes out version number to file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
     * @param newVersion if true, writes to a new version file
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
     * @exception IOException If an I/O error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
    private void writeVersionFile(boolean newVersion) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        String name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        if (newVersion) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
            name = newVersionFile;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
            name = versionFile;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        }
12040
558b0e0d5910 7146763: Warnings cleanup in the sun.rmi and related packages
khazra
parents: 9502
diff changeset
   597
        try (FileOutputStream fos = new FileOutputStream(fName(name));
558b0e0d5910 7146763: Warnings cleanup in the sun.rmi and related packages
khazra
parents: 9502
diff changeset
   598
             DataOutputStream out = new DataOutputStream(fos)) {
558b0e0d5910 7146763: Warnings cleanup in the sun.rmi and related packages
khazra
parents: 9502
diff changeset
   599
            writeInt(out, version);
558b0e0d5910 7146763: Warnings cleanup in the sun.rmi and related packages
khazra
parents: 9502
diff changeset
   600
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     * Creates the initial version file
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
     * @exception IOException If an I/O error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
    private void createFirstVersion() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        version = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
        writeVersionFile(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
     * Commits (atomically) the new version.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
     * @exception IOException If an I/O error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    private void commitToNewVersion() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
        writeVersionFile(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
        deleteNewVersionFile();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
     * Reads version number from a file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
     * @param name the name of the version file
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
     * @return the version
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
     * @exception IOException If an I/O error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
    private int readVersion(String name) throws IOException {
12040
558b0e0d5910 7146763: Warnings cleanup in the sun.rmi and related packages
khazra
parents: 9502
diff changeset
   631
        try (DataInputStream in = new DataInputStream
558b0e0d5910 7146763: Warnings cleanup in the sun.rmi and related packages
khazra
parents: 9502
diff changeset
   632
                (new FileInputStream(name))) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
            return in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
     * Sets the version.  If version file does not exist, the initial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
     * version file is created.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
     * @exception IOException If an I/O error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    private void getVersion() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
            version = readVersion(fName(newVersionFile));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
            commitToNewVersion();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
                deleteNewVersionFile();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
            catch (IOException ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
                version = readVersion(fName(versionFile));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
            catch (IOException ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
                createFirstVersion();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
     * Applies outstanding updates to the snapshot.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
     * @param state the most recent snapshot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
     * @exception IOException If serious log corruption is detected or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
     * if an exception occurred during a readUpdate callback or if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
     * other I/O error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
     * @return the resulting state of the object after all updates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
    private Object recoverUpdates(Object state)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
        logBytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        logEntries = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        if (version == 0) return state;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        String fname = versionName(logfilePrefix);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
        InputStream in =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                new BufferedInputStream(new FileInputStream(fname));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
        DataInputStream dataIn = new DataInputStream(in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
        if (Debug)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
            System.err.println("log.debug: reading updates from " + fname);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
            majorFormatVersion = dataIn.readInt(); logBytes += intBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
            minorFormatVersion = dataIn.readInt(); logBytes += intBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        } catch (EOFException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
            /* This is a log which was corrupted and/or cleared (by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
             * fsck or equivalent).  This is not an error.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
            openLogFile(true);  // create and truncate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
            in = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        /* A new major version number is a catastrophe (it means
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
         * that the file format is incompatible with older
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
         * clients, and we'll only be breaking things by trying to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
         * use the log).  A new minor version is no big deal for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
         * upward compatibility.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
        if (majorFormatVersion != PreferredMajorVersion) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
            if (Debug) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
                System.err.println("log.debug: major version mismatch: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
                        majorFormatVersion + "." + minorFormatVersion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
            throw new IOException("Log file " + logName + " has a " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
                                  "version " + majorFormatVersion +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                                  "." + minorFormatVersion +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
                                  " format, and this implementation " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
                                  " understands only version " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                                  PreferredMajorVersion + "." +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                                  PreferredMinorVersion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            while (in != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                int updateLen = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                    updateLen = dataIn.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                } catch (EOFException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
                    if (Debug)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
                        System.err.println("log.debug: log was sync'd cleanly");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
                if (updateLen <= 0) {/* crashed while writing last log entry */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
                    if (Debug) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
                        System.err.println(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
                            "log.debug: last update incomplete, " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
                            "updateLen = 0x" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
                            Integer.toHexString(updateLen));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
                // this is a fragile use of available() which relies on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
                // twin facts that BufferedInputStream correctly consults
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
                // the underlying stream, and that FileInputStream returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
                // the number of bytes remaining in the file (via FIONREAD).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
                if (in.available() < updateLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
                    /* corrupted record at end of log (can happen since we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
                     * do only one fsync)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
                    if (Debug)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
                        System.err.println("log.debug: log was truncated");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
                if (Debug)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
                    System.err.println("log.debug: rdUpdate size " + updateLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                    state = handler.readUpdate(new LogInputStream(in, updateLen),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
                                          state);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                    throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                    e.printStackTrace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                    throw new IOException("read update failed with " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                                          "exception: " + e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
                logBytes += (intBytes + updateLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                logEntries++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
            } /* while */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
            if (in != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
                in.close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        if (Debug)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            System.err.println("log.debug: recovered updates: " + logEntries);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
        /* reopen log file at end */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
        openLogFile(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
        // avoid accessing a null log field
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
        if (log == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            throw new IOException("rmid's log is inaccessible, " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                "it may have been corrupted or closed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
        log.seek(logBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
        log.setLength(logBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
        return state;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
     * ReliableLog's log file implementation.  This implementation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
     * is subclassable for testing purposes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
    public static class LogFile extends RandomAccessFile {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
        private final FileDescriptor fd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
         * Constructs a LogFile and initializes the file descriptor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
         **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
        public LogFile(String name, String mode)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
            throws FileNotFoundException, IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
            super(name, mode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
            this.fd = getFD();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
         * Invokes sync on the file descriptor for this log file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
        protected void sync() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
            fd.sync();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
         * Returns true if writing 4 bytes starting at the specified file
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
         * position, would span a 512 byte sector boundary; otherwise returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
         * false.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
         **/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        protected boolean checkSpansBoundary(long fp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
            return  fp % 512 > 508;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
}