1 9 10 package com.sleepycat.collections; 11 12 import java.util.Comparator; 13 14 import com.sleepycat.je.DatabaseEntry; 15 16 19 class KeyRange { 20 21 Comparator comparator; 22 DatabaseEntry beginKey; 23 DatabaseEntry endKey; 24 boolean singleKey; 25 boolean beginInclusive; 26 boolean endInclusive; 27 28 31 KeyRange(Comparator comparator) { 32 this.comparator = comparator; 33 } 34 35 38 KeyRange subRange(DatabaseEntry key) 39 throws KeyRangeException { 40 41 if (!check(key)) { 42 throw new KeyRangeException("singleKey out of range"); 43 } 44 KeyRange range = new KeyRange(comparator); 45 range.beginKey = key; 46 range.endKey = key; 47 range.beginInclusive = true; 48 range.endInclusive = true; 49 range.singleKey = true; 50 return range; 51 } 52 53 57 KeyRange subRange(DatabaseEntry beginKey, boolean beginInclusive, 58 DatabaseEntry endKey, boolean endInclusive) 59 throws KeyRangeException { 60 61 if (beginKey == null) { 62 beginKey = this.beginKey; 63 beginInclusive = this.beginInclusive; 64 } else if (!check(beginKey, beginInclusive)) { 65 throw new KeyRangeException("beginKey out of range"); 66 } 67 if (endKey == null) { 68 endKey = this.endKey; 69 endInclusive = this.endInclusive; 70 } else if (!check(endKey, endInclusive)) { 71 throw new KeyRangeException("endKey out of range"); 72 } 73 KeyRange range = new KeyRange(comparator); 74 range.beginKey = beginKey; 75 range.endKey = endKey; 76 range.beginInclusive = beginInclusive; 77 range.endInclusive = endInclusive; 78 return range; 79 } 80 81 85 final DatabaseEntry getSingleKey() { 86 87 return singleKey ? beginKey : null; 88 } 89 90 93 final boolean hasBound() { 94 95 return endKey != null || beginKey != null; 96 } 97 98 101 public String toString() { 102 103 return "[KeyRange " + beginKey + ' ' + beginInclusive + 104 endKey + ' ' + endInclusive + 105 (singleKey ? " single" : ""); 106 } 107 108 111 boolean check(DatabaseEntry key) { 112 113 if (singleKey) { 114 return (compare(key, beginKey) == 0); 115 } else { 116 return checkBegin(key, true) && checkEnd(key, true); 117 } 118 } 119 120 123 boolean check(DatabaseEntry key, boolean inclusive) { 124 125 if (singleKey) { 126 return (compare(key, beginKey) == 0); 127 } else { 128 return checkBegin(key, inclusive) && checkEnd(key, inclusive); 129 } 130 } 131 132 148 boolean checkBegin(DatabaseEntry key, boolean inclusive) { 149 150 if (beginKey == null) { 151 return true; 152 } else if (!beginInclusive && inclusive) { 153 return compare(key, beginKey) > 0; 154 } else { 155 return compare(key, beginKey) >= 0; 156 } 157 } 158 159 163 boolean checkEnd(DatabaseEntry key, boolean inclusive) { 164 165 if (endKey == null) { 166 return true; 167 } else if (!endInclusive && inclusive) { 168 return compare(key, endKey) < 0; 169 } else { 170 return compare(key, endKey) <= 0; 171 } 172 } 173 174 177 int compare(DatabaseEntry key1, DatabaseEntry key2) { 178 179 if (comparator != null) { 180 return comparator.compare(getByteArray(key1), getByteArray(key2)); 181 } else { 182 return compareBytes 183 (key1.getData(), key1.getOffset(), key1.getSize(), 184 key2.getData(), key2.getOffset(), key2.getSize()); 185 186 } 187 } 188 189 193 static int compareBytes(byte[] data1, int offset1, int size1, 194 byte[] data2, int offset2, int size2) { 195 196 for (int i = 0; i < size1 && i < size2; i++) { 197 198 int b1 = 0xFF & data1[offset1 + i]; 199 int b2 = 0xFF & data2[offset2 + i]; 200 if (b1 < b2) 201 return -1; 202 else if (b1 > b2) 203 return 1; 204 } 205 206 if (size1 < size2) 207 return -1; 208 else if (size1 > size2) 209 return 1; 210 else 211 return 0; 212 } 213 214 217 static DatabaseEntry copy(DatabaseEntry from) { 218 return new DatabaseEntry(getByteArray(from)); 219 } 220 221 224 static void copy(DatabaseEntry from, DatabaseEntry to) { 225 to.setData(getByteArray(from)); 226 to.setOffset(0); 227 } 228 229 233 static byte[] getByteArray(DatabaseEntry entry) { 234 235 byte[] bytes = entry.getData(); 236 if (bytes == null) return null; 237 int size = entry.getSize(); 238 byte[] data = new byte[size]; 239 System.arraycopy(bytes, entry.getOffset(), data, 0, size); 240 return data; 241 } 242 243 246 static boolean equalBytes(DatabaseEntry e1, DatabaseEntry e2) { 247 248 if (e1 == null && e2 == null) { 249 return true; 250 } 251 if (e1 == null || e2 == null) { 252 return false; 253 } 254 255 byte[] d1 = e1.getData(); 256 byte[] d2 = e2.getData(); 257 int s1 = e1.getSize(); 258 int s2 = e2.getSize(); 259 int o1 = e1.getOffset(); 260 int o2 = e2.getOffset(); 261 262 if (d1 == null && d2 == null) { 263 return true; 264 } 265 if (d1 == null || d2 == null) { 266 return false; 267 } 268 if (s1 != s2) { 269 return false; 270 } 271 for (int i = 0; i < s1; i += 1) { 272 if (d1[o1 + i] != d2[o2 + i]) { 273 return false; 274 } 275 } 276 return true; 277 } 278 279 287 static String toString(DatabaseEntry dbt) { 288 289 int len = dbt.getOffset() + dbt.getSize(); 290 StringBuffer buf = new StringBuffer(len * 2); 291 byte[] data = dbt.getData(); 292 for (int i = dbt.getOffset(); i < len; i++) { 293 String num = Integer.toHexString(data[i]); 294 if (num.length() < 2) buf.append('0'); 295 buf.append(num); 296 } 297 return buf.toString(); 298 } 299 } 300 | Popular Tags |