1 8 9 package com.sleepycat.je.utilint; 10 11 import java.util.Arrays ; 12 13 import com.sleepycat.je.log.FileManager; 14 import com.sleepycat.je.log.LogReadable; 15 import com.sleepycat.je.tree.TreeUtils; 16 17 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 lsn) { 41 if (lsn == null) { 42 return NULL_LSN; 43 } 44 45 return lsn.longValue(); 46 } 47 48 52 public static long getFileNumber(long lsn) { 53 return (lsn >> 32) & INT_MASK; 54 } 55 56 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 (); 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 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 getNoFormatString(long lsn) { 98 return "0x" + Long.toHexString(getFileNumber(lsn)) + "/0x" + 99 Long.toHexString(getFileOffset(lsn)); 100 } 101 102 public static String dumpString(long lsn, int nSpaces) { 103 StringBuffer sb = new StringBuffer (); 104 sb.append(TreeUtils.indent(nSpaces)); 105 sb.append(toString(lsn)); 106 return sb.toString(); 107 } 108 109 114 public static long getNoCleaningDistance(long thisLsn, 115 long otherLsn, 116 long logFileSize) { 117 long diff = 0; 118 119 assert thisLsn != NULL_LSN; 120 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 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 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 160 Long [] fileNums = fileManager.getAllFileNumbers(); 161 int myFileIdx = Arrays.binarySearch(fileNums, 162 new Long (myFile)); 163 int otherFileIdx = Arrays.binarySearch(fileNums, 164 new Long (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 189 public boolean logEntryIsTransactionalX() { 190 return false; 191 } 192 193 196 public long getTransactionIdX() { 197 return 0; 198 } 199 } 200 | Popular Tags |