KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > utilint > DbLsn


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: DbLsn.java,v 1.50 2006/10/30 21:14:28 bostic Exp $
7  */

8
9 package com.sleepycat.je.utilint;
10
11 import java.util.Arrays JavaDoc;
12
13 import com.sleepycat.je.log.FileManager;
14 import com.sleepycat.je.log.LogReadable;
15 import com.sleepycat.je.tree.TreeUtils;
16
17 /**
18  * DbLsn is a class that operates on Log Sequence Numbers (LSNs). An LSN is a
19  * long comprised of a file number (32b) and offset within that file (32b)
20  * which references a unique record in the database environment log. While
21  * LSNs are represented as long's, we operate on them using an abstraction and
22  * return longs from these methods so that we don't have to worry about the
23  * lack of unsigned quantities.
24  */

25 public class DbLsn {
26     static final long INT_MASK = 0xFFFFFFFFL;
27
28     public static final long MAX_FILE_OFFSET = 0xFFFFFFFFL;
29
30     public static final long NULL_LSN = -1;
31
32     private DbLsn() {
33     }
34
35     public static long makeLsn(long fileNumber, long fileOffset) {
36     return fileOffset & INT_MASK |
37         ((fileNumber & INT_MASK) << 32);
38     }
39
40     public static long longToLsn(Long JavaDoc lsn) {
41     if (lsn == null) {
42         return NULL_LSN;
43     }
44
45     return lsn.longValue();
46     }
47
48     /**
49      * Return the file number for this DbLsn.
50      * @return the number for this DbLsn.
51      */

52     public static long getFileNumber(long lsn) {
53     return (lsn >> 32) & INT_MASK;
54     }
55
56     /**
57      * Return the file offset for this DbLsn.
58      * @return the offset for this DbLsn.
59      */

60     public static long getFileOffset(long lsn) {
61     return (lsn & INT_MASK);
62     }
63
64     private static int compareLong(long l1, long l2) {
65     if (l1 < l2) {
66         return -1;
67     } else if (l1 > l2) {
68         return 1;
69     } else {
70         return 0;
71     }
72     }
73
74     public static int compareTo(long lsn1, long lsn2) {
75     if (lsn1 == NULL_LSN ||
76         lsn2 == NULL_LSN) {
77         throw new NullPointerException JavaDoc();
78     }
79
80         long fileNumber1 = getFileNumber(lsn1);
81         long fileNumber2 = getFileNumber(lsn2);
82         if (fileNumber1 == fileNumber2) {
83             return compareLong(getFileOffset(lsn1), getFileOffset(lsn2));
84         } else {
85             return compareLong(fileNumber1, fileNumber2);
86         }
87     }
88
89     public static String JavaDoc toString(long lsn) {
90     return "<DbLsn val=\"0x" +
91             Long.toHexString(getFileNumber(lsn)) +
92             "/0x" +
93             Long.toHexString(getFileOffset(lsn)) +
94         "\"/>";
95     }
96
97     public static String JavaDoc getNoFormatString(long lsn) {
98         return "0x" + Long.toHexString(getFileNumber(lsn)) + "/0x" +
99             Long.toHexString(getFileOffset(lsn));
100     }
101
102     public static String JavaDoc dumpString(long lsn, int nSpaces) {
103         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
104         sb.append(TreeUtils.indent(nSpaces));
105         sb.append(toString(lsn));
106         return sb.toString();
107     }
108
109     /**
110      * Return the logsize in bytes between these two LSNs. This is an
111      * approximation; the logs might actually be a little more or less in
112      * size. This assumes that no log files have been cleaned.
113      */

114     public static long getNoCleaningDistance(long thisLsn,
115                          long otherLsn,
116                          long logFileSize) {
117         long diff = 0;
118
119     assert thisLsn != NULL_LSN;
120         /* First figure out how many files lay between the two. */
121         long myFile = getFileNumber(thisLsn);
122     if (otherLsn == NULL_LSN) {
123         otherLsn = 0;
124     }
125         long otherFile = getFileNumber(otherLsn);
126         if (myFile == otherFile) {
127             diff = Math.abs(getFileOffset(thisLsn) - getFileOffset(otherLsn));
128         } else if (myFile > otherFile) {
129             diff = calcDiff(myFile - otherFile,
130                             logFileSize, thisLsn, otherLsn);
131         } else {
132             diff = calcDiff(otherFile - myFile,
133                             logFileSize, otherLsn, thisLsn);
134         }
135         return diff;
136     }
137         
138     /**
139      * Return the logsize in bytes between these two LSNs. This is an
140      * approximation; the logs might actually be a little more or less in
141      * size. This assumes that log files might have been cleaned.
142      */

143     public static long getWithCleaningDistance(long thisLsn,
144                            FileManager fileManager,
145                            long otherLsn,
146                            long logFileSize) {
147         long diff = 0;
148
149     assert thisLsn != NULL_LSN;
150         /* First figure out how many files lay between the two. */
151         long myFile = getFileNumber(thisLsn);
152     if (otherLsn == NULL_LSN) {
153         otherLsn = 0;
154     }
155         long otherFile = getFileNumber(otherLsn);
156         if (myFile == otherFile) {
157             diff = Math.abs(getFileOffset(thisLsn) - getFileOffset(otherLsn));
158         } else {
159             /* Figure out how many files lie between. */
160             Long JavaDoc[] fileNums = fileManager.getAllFileNumbers();
161             int myFileIdx = Arrays.binarySearch(fileNums,
162                                                 new Long JavaDoc(myFile));
163             int otherFileIdx = Arrays.binarySearch(fileNums,
164                                                    new Long JavaDoc(otherFile));
165             if (myFileIdx > otherFileIdx) {
166                 diff = calcDiff(myFileIdx - otherFileIdx,
167                                 logFileSize, thisLsn, otherLsn);
168             } else {
169                 diff = calcDiff(otherFileIdx - myFileIdx,
170                                 logFileSize, otherLsn, thisLsn);
171             }
172         }
173         return diff;
174     }
175
176     private static long calcDiff(long fileDistance,
177                  long logFileSize,
178                  long laterLsn,
179                  long earlierLsn) {
180         long diff = fileDistance * logFileSize;
181         diff += getFileOffset(laterLsn);
182         diff -= getFileOffset(earlierLsn);
183         return diff;
184     }
185
186     /**
187      * @see LogReadable#logEntryIsTransactional.
188      */

189     public boolean logEntryIsTransactionalX() {
190     return false;
191     }
192
193     /**
194      * @see LogReadable#getTransactionId
195      */

196     public long getTransactionIdX() {
197     return 0;
198     }
199 }
200
Popular Tags