KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > store > raw > log > LogCounter


1 /*
2
3    Derby - Class org.apache.derby.impl.store.raw.log.LogCounter
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.store.raw.log;
23
24 import org.apache.derby.iapi.services.sanity.SanityManager;
25 import org.apache.derby.iapi.services.io.FormatIdUtil;
26 import org.apache.derby.iapi.services.io.StoredFormatIds;
27 import org.apache.derby.iapi.store.raw.log.LogInstant;
28 import org.apache.derby.iapi.store.access.DatabaseInstant;
29 import org.apache.derby.iapi.services.io.CompressedNumber;
30
31 import java.io.IOException JavaDoc;
32 import java.io.ObjectInput JavaDoc;
33 import java.io.ObjectOutput JavaDoc;
34
35 /**
36     A very simple log instant implementation.
37
38     Within the stored log record a log counter is represented as a long,
39     hence the getValueAsLong() method. Outside the LogFactory the instant
40     is passed around as a LogCounter (through its LogInstant interface).
41
42     The way the long is encoded is such that < == > correctly tells if
43     one log instant is lessThan, equals or greater than another.
44
45 */

46 public class LogCounter implements LogInstant {
47
48     /********************************************************
49     **
50     ** This class implements Formatable. That means that it
51     ** can write itself to and from a formatted stream. If
52     ** you add more fields to this class, make sure that you
53     ** also write/read them with the writeExternal()/readExternal()
54     ** methods.
55     **
56     ** If, between releases, you add more fields to this class,
57     ** then you should bump the version number emitted by the getTypeFormatId()
58     ** method.
59     **
60     ********************************************************/

61     
62     /** A well defined value of an invalid log instant. */
63     public static final long INVALID_LOG_INSTANT = 0;
64     
65     // max possible log file number in versions before 10.1 is 2^22 -1
66
public static final long DERBY_10_0_MAX_LOGFILE_NUMBER = (long)0x003FFFFFL; // 4194303
67
// max possible log file number is 2^31 -1
68
public static final long MAX_LOGFILE_NUMBER = (long)0x7FFFFFFFL; // 2147483647
69
// lower end of 32 bits in long type are used to store the log file position
70
private static final long FILE_NUMBER_SHIFT = 32;
71
72     // reserve top 4 bits in log file size for future use
73
public static final long MAX_LOGFILE_SIZE = (long)0x0FFFFFFFL; // 268435455
74
// 32 bits are used to store the log file postion
75
private static final long FILE_POSITION_MASK = (long)0x7FFFFFFFL;
76
77     private long fileNumber;
78     private long filePosition;
79
80     // contructors
81
public LogCounter(long value) {
82         fileNumber = getLogFileNumber(value);
83         filePosition = getLogFilePosition(value);
84     }
85
86     public LogCounter(long fileNumber, long position) {
87
88         if (SanityManager.DEBUG) {
89             SanityManager.ASSERT(fileNumber > 0, "illegal fileNumber");
90             SanityManager.ASSERT(position > 0, "illegal file position");
91
92             SanityManager.ASSERT(position < MAX_LOGFILE_SIZE,
93                              "log file position exceeded max log file size");
94             SanityManager.ASSERT(fileNumber < MAX_LOGFILE_NUMBER,
95                              "log file number exceeded max log file number");
96         }
97
98         this.fileNumber = fileNumber;
99         this.filePosition = position;
100     }
101
102     /**
103      * Public niladic constructor needed for Formatable interface.
104      */

105     public LogCounter() {}
106     
107     /**
108         Static functions that can only be used inside the RawStore's log
109         factory which passes the log counter around encoded as a long
110     */

111
112     // make a log instant from 2 longs and return a long which is the long
113
// representatin of a LogCounter
114
static public final long makeLogInstantAsLong(long filenum, long filepos)
115     {
116         if (SanityManager.DEBUG) {
117             SanityManager.ASSERT(filenum > 0, "illegal fileNumber");
118             SanityManager.ASSERT(filepos > 0, "illegal file position");
119
120             SanityManager.ASSERT(filepos < MAX_LOGFILE_SIZE,
121                              "log file position exceeded max log file size");
122             SanityManager.ASSERT(filenum < MAX_LOGFILE_NUMBER,
123                              "log file number exceeded max log file number");
124         }
125
126         return ((filenum << FILE_NUMBER_SHIFT) | filepos);
127     }
128
129
130     static public final long getLogFilePosition(long valueAsLong)
131     {
132         return valueAsLong & FILE_POSITION_MASK;
133     }
134
135     static public final long getLogFileNumber(long valueAsLong)
136     {
137         return valueAsLong >>> FILE_NUMBER_SHIFT;
138     }
139
140     /** LogScan methods */
141
142     public boolean lessThan(DatabaseInstant other) {
143         LogCounter compare = (LogCounter)other;
144
145         return (fileNumber == compare.fileNumber) ?
146             filePosition < compare.filePosition :
147             fileNumber < compare.fileNumber;
148     }
149
150     public boolean equals(Object JavaDoc other) {
151         if (this == other)
152             return true;
153
154         if (!(other instanceof LogCounter))
155             return false;
156
157         LogCounter compare = (LogCounter)other;
158
159         return fileNumber == compare.fileNumber &&
160             filePosition == compare.filePosition;
161     }
162
163     public DatabaseInstant next() {
164         return new LogCounter( makeLogInstantAsLong(fileNumber, filePosition) + 1);
165     }
166     
167     public DatabaseInstant prior() {
168         return new LogCounter( makeLogInstantAsLong(fileNumber, filePosition) - 1);
169     }
170     
171     public int hashCode() {
172         return (int) (filePosition ^ fileNumber);
173     }
174
175     public String JavaDoc toString() {
176         return "(" + fileNumber + "," + filePosition + ")";
177     }
178
179     public static String JavaDoc toDebugString(long instant)
180     {
181         if (SanityManager.DEBUG)
182             return "(" + getLogFileNumber(instant) + "," + getLogFilePosition(instant) + ")";
183         else
184             return null;
185     }
186
187     /**
188         These following methods are only intended to be called by an
189         implementation of a log factory. All other uses of this object should
190         only see it as a log instant.
191     */

192     public long getValueAsLong() {
193         return makeLogInstantAsLong(fileNumber, filePosition);
194     }
195
196     public long getLogFilePosition()
197     {
198          return filePosition;
199     }
200
201     public long getLogFileNumber()
202     {
203         return fileNumber;
204     }
205
206     
207     /*
208      * methods for the Formatable interface
209      */

210
211     /**
212      * Read this in.
213      * @exception IOException error reading from log stream
214      * @exception ClassNotFoundException corrupted log stream
215      */

216     public void readExternal(ObjectInput JavaDoc oi) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
217         fileNumber = CompressedNumber.readLong(oi);
218         filePosition = CompressedNumber.readLong(oi);
219     }
220     
221     /**
222      * Write this out.
223      * @exception IOException error writing to log stream
224      */

225     public void writeExternal(ObjectOutput JavaDoc oo) throws IOException JavaDoc {
226         CompressedNumber.writeLong(oo,fileNumber);
227         CompressedNumber.writeLong(oo,filePosition);
228     }
229     
230     /**
231      * Get the formatID which corresponds to this class.
232      *
233      * @return the formatID of this class
234      */

235     public int getTypeFormatId() { return StoredFormatIds.LOG_COUNTER; }
236
237 }
238
Popular Tags