1 19 package org.netbeans.mdr.persistence.btreeimpl.btreeindex; 20 import org.netbeans.mdr.persistence.*; 21 import java.io.*; 22 23 44 public class BigKeyPage extends BtreePage { 45 46 private int keyLength; 47 48 public BigKeyPage() {} 49 50 60 public void init(Btree btree, byte[] pageId, byte[] pageBuffer, 61 boolean isNew) throws StorageException { 62 63 if (initialized) { 64 65 return; 66 } 67 68 super.init(btree, pageId, pageBuffer, isNew); 69 if (isNew) { 70 keyLength = 0; 71 flags = 0; 72 } else { 73 76 keyLength = freeStart; 77 } 78 } 79 80 83 public void store() { 84 85 freeStart = keyLength; 86 super.store(); 87 } 88 89 94 int numEntries() { 95 return 1; 96 } 97 98 105 int keyOffset(int entryNum) { 106 return headerLength; 107 } 108 109 116 int keyLength(int entryNum) { 117 return keyLength; 118 } 119 120 127 byte[] getData(int entryNum) throws StorageException { 128 129 byte[] data = new byte[dataLength]; 130 int pageSpace = btree.pageSize - headerLength; 131 132 if ((keyLength + dataLength) < pageSpace) { 133 System.arraycopy(pageBuffer, headerLength + keyLength, 134 data, 0, dataLength); 135 } else { 136 SearchResult location = getDataLocation(); 137 System.arraycopy(location.page.pageBuffer, location.entryNum, 138 data, 0, dataLength); 139 if (location.page != this) { 140 pageSource.unpinPage(location.page); 141 } 142 } 143 return data; 144 } 145 146 private SearchResult getDataLocation() throws StorageException { 147 148 BtreePage current; 149 byte[] next; 150 int left; 151 int pageSpace = btree.pageSize - headerLength; 152 153 154 current = this; 155 left = keyLength; 156 while (left > pageSpace) { 157 left -= pageSpace; 158 next = current.nextPage; 159 if (current != this) { 160 pageSource.unpinPage(current); 161 } 162 current = pageSource.getPage(next, btree); 163 } 164 if ((left + dataLength) <= pageSpace) { 165 166 return new SearchResult(true, headerLength+left, current); 167 } else { 168 169 next = current.nextPage; 170 if (current != this) { 171 pageSource.unpinPage(current); 172 } 173 current = pageSource.getPage(next, btree); 174 return new SearchResult(true, headerLength, current); 175 } 176 } 177 184 byte[] getKey(int entryNum) throws StorageException { 185 186 byte[] next; 187 byte[] key = new byte[keyLength]; 188 int pageSpace = btree.pageSize - headerLength; 189 190 if (keyLength < pageSpace) { 191 System.arraycopy(pageBuffer, headerLength, 192 key, 0, keyLength); 193 } else { 194 BtreePage page = this; 195 int left = keyLength; 196 while (left > pageSpace) { 197 System.arraycopy(page.pageBuffer, headerLength, 198 key, keyLength - left, pageSpace); 199 left -= pageSpace; 200 next = page.nextPage; 201 if (page != this) { 202 pageSource.unpinPage(page); 203 } 204 page = pageSource.getPage(next, btree); 205 } 206 if (left > 0) { 207 System.arraycopy(page.pageBuffer, headerLength, 208 key, keyLength - left, left); 209 } 210 if (page != this) { 211 pageSource.unpinPage(page); 212 } 213 } 214 return key; 215 } 216 217 226 227 BtreeEntry replace(BtreeEntry entry, int entryNum, SearchResult resultPosition) throws StorageException { 228 229 SearchResult location; 230 231 pageSource.dirtyPage(this); 232 location = getDataLocation(); 233 if (location.page != this) { 234 pageSource.dirtyPage(location.page); 235 } 236 System.arraycopy(entry.data, 0, location.page.pageBuffer, 237 location.entryNum, entry.data.length); 238 if (location.page != this) { 239 pageSource.unpinPage(location.page); 240 } 241 242 if (resultPosition != null) { 244 resultPosition.matched = true; 245 resultPosition.skipCount = 0; 246 resultPosition.page = this; 247 resultPosition.entryNum = entryNum; 248 } 249 250 return null; 251 } 252 253 262 BtreeEntry insert(BtreeEntry entry, int entryNum, SearchResult resultPosition) 263 throws StorageException { 264 265 BigKeyPage current, previous, newNext; 266 BtreePage newPrevious; 267 byte[] next; 268 int left; 269 int pageSpace = btree.pageSize - headerLength; 270 271 if (keyLength == 0) { 272 273 current = this; 274 pageSource.dirtyPage(current); 275 newNext = null; 276 } else { 277 278 current = pageSource.newBigKeyPage(btree); 279 if (entryNum == 0) { 280 281 newPrevious = pageSource.getPage(this.previousPage, btree); 282 newNext = this; 283 pageSource.dirtyPage(this); 284 } else { 285 286 newNext = null; 287 newPrevious = this; 288 next = newPrevious.nextPage; 289 while (!pageSource.isNoPage(next)) { 290 if (newPrevious != this) { 291 pageSource.unpinPage(newPrevious); 292 } 293 newPrevious = pageSource.getPage(next, btree); 294 next = newPrevious.nextPage; 295 } 296 } 297 pageSource.dirtyPage(newPrevious); 298 linkNewPage(current, newPrevious, newNext); 299 pageSource.unpinPage(newPrevious); 300 } 301 302 if (resultPosition != null) { 304 resultPosition.matched = true; 305 resultPosition.skipCount = 0; 306 resultPosition.page = current; 307 resultPosition.entryNum = entryNum; } 309 310 current.keyLength = entry.key.length; 311 312 left = entry.key.length; 313 while (left > pageSpace) { 314 System.arraycopy(entry.key, entry.key.length - left, 315 current.pageBuffer, headerLength, pageSpace); 316 left -= pageSpace; 317 previous = current; 318 current = pageSource.newBigKeyPage(btree); 319 linkNewPage(current, previous, newNext); 320 if (previous != this) { 321 pageSource.unpinPage(previous); 322 } 323 } 324 if (left > 0) { 325 System.arraycopy(entry.key, entry.key.length - left, 326 current.pageBuffer, headerLength, left); 327 } 328 if ((left + dataLength) > pageSpace) { 329 previous = current; 330 current = pageSource.newBigKeyPage(btree); 331 linkNewPage(current, previous, newNext); 332 if (previous != this) { 333 pageSource.unpinPage(previous); 334 } 335 left = 0; 336 } 337 System.arraycopy(entry.data, 0, current.pageBuffer, headerLength + left, 338 dataLength); 339 if (current != this) { 340 pageSource.unpinPage(current); 341 } 342 if ((newNext != null) && (newNext != this)) { 343 pageSource.unpinPage(newNext); 344 } 345 return null; 346 } 347 348 private void linkNewPage(BtreePage newPage, BtreePage left, 349 BtreePage right) { 350 System.arraycopy(left.pageId, 0, newPage.previousPage, 0, 351 left.pageId.length); 352 System.arraycopy(left.nextPage, 0, newPage.nextPage, 0, 353 left.pageId.length); 354 System.arraycopy(newPage.pageId, 0, left.nextPage, 0, 355 newPage.pageId.length); 356 if (right != null) { 357 System.arraycopy(newPage.pageId, 0, right.previousPage, 0, 358 newPage.pageId.length); 359 } 360 } 361 362 368 369 void delete(int first, int last) throws StorageException { 370 371 BtreePage next, previous, current; 372 int pageSpace = btree.pageSize - headerLength; 373 int left = keyLength; 374 375 current = this; 376 previous = pageSource.getPage(this.previousPage, btree); 377 pageSource.dirtyPage(previous); 378 while (left > pageSpace) { 379 left -= pageSpace; 380 next = pageSource.getPage(current.nextPage, btree); 381 if (current != this) { 382 pageSource.unpinPage(current); 383 } 384 current = next; 385 } 386 if ((left + dataLength) > pageSpace) { 387 388 next = pageSource.getPage(current.nextPage, btree); 389 pageSource.unpinPage(current); 390 current = next; 391 } 392 393 System.arraycopy(current.nextPage, 0, previous.nextPage, 0, 394 current.nextPage.length); 395 if (!pageSource.isNoPage(current.nextPage)) { 396 next = pageSource.getPage(current.nextPage, btree); 397 pageSource.dirtyPage(next); 398 System.arraycopy(previous.pageId, 0, next.previousPage, 0, 399 previous.pageId.length); 400 pageSource.unpinPage(next); 401 } 402 if (previous.isRoot() && pageSource.isNoPage(previous.nextPage)) { 403 btree.unsetHasBigKeys(); 404 } 405 pageSource.unpinPage(previous); 406 if (current != this) { 407 pageSource.unpinPage(current); 408 } 409 } 410 411 414 byte[] splitEntries(BtreePage leftBP, BtreePage rightBP, BtreeEntry entry, 415 int newEntryNum, SearchResult resultPosition) throws StorageException { 416 return null; 417 } 418 419 423 SearchResult searchBigKeys(byte[] key) throws StorageException { 424 425 BigKeyPage current, next; 426 byte[] currentKey; 427 SearchResult result; 428 byte compare; 429 430 next = this; 431 result = null; 432 do { 433 current = next; 434 currentKey = current.getKey(0); 435 compare = btree.keyInfo.compare(key, currentKey, 0, currentKey.length); 436 if (compare == EntryTypeInfo.EQUAL) { 437 result = new SearchResult(true, 0, current); 438 } else if (compare == EntryTypeInfo.LESS) { 439 result = new SearchResult(false, 0, current); 440 } else { 441 next = current.getNextKeyStart(); 442 if (current != this) { 443 pageSource.unpinPage(current); 444 } 445 } 446 } while ((result == null) && (next != null)); 447 448 if (result == null) { 449 result = new SearchResult(false, 1, current); 450 } 451 return result; 452 } 453 454 463 static void getNext(byte[] key, SearchResult result, boolean testOnly) 464 throws StorageException { 465 466 BigKeyPage page; 467 byte[] currentKey; 468 Btree btree = result.page.btree; 469 470 if (result.entryNum == -1) { 471 page = (BigKeyPage)result.page; 472 if (!testOnly) { 473 result.entryNum = 0; 474 } 475 } else { 476 page = ((BigKeyPage)result.page).getNextKeyStart(); 477 } 478 if (page == null) { 479 result.matched = false; 480 result.entryNum = 1; 481 return; 482 } 483 484 if (key != null) { 485 currentKey = page.getKey(0); 486 if (btree.keyInfo.compare(key, currentKey, 0, currentKey.length) 487 == EntryTypeInfo.EQUAL) { 488 result.matched = true; 489 } else { 490 result.matched = false; 491 } 492 } else { 493 result.matched = true; 494 } 495 if (!testOnly) { 496 result.page = page; 497 } 498 } 499 500 BigKeyPage getNextKeyStart() throws StorageException { 501 502 BigKeyPage next, currentDataPage; 503 504 currentDataPage = (BigKeyPage) getDataLocation().page; 505 if (!pageSource.isNoPage(currentDataPage.nextPage)) { 506 next = (BigKeyPage) pageSource.getPage(currentDataPage.nextPage, 507 btree); 508 } else { 509 next = null; 510 } 511 if (currentDataPage != this) { 512 pageSource.unpinPage(currentDataPage); 513 } 514 return next; 515 } 516 517 524 static void getPrevious(byte[] key, SearchResult result, boolean testOnly) 525 throws StorageException { 526 BigKeyPage page; 527 byte[] currentKey; 528 Btree btree = result.page.btree; 529 530 page = ((BigKeyPage)result.page).getPreviousKeyStart(); 531 if (page == null) { 532 if (!testOnly) { 533 result.entryNum = -1; 534 } 535 result.matched = false; 536 return; 537 } 538 539 if (key != null) { 540 currentKey = page.getKey(0); 541 if (btree.keyInfo.compare(key, currentKey, 0, currentKey.length) 542 == EntryTypeInfo.EQUAL) { 543 result.matched = true; 544 } else { 545 result.matched = false; 546 } 547 } else { 548 result.matched = true; 549 } 550 if (!testOnly) { 551 result.page = page; 552 } 553 } 554 555 BigKeyPage getPreviousKeyStart() throws StorageException { 556 557 int currentLength = 0; 558 BtreePage current, previous; 559 560 current = this; 561 do { 562 previous = pageSource.getPage(current.previousPage, btree); 563 if (current != this) { 564 pageSource.unpinPage(current); 565 } 566 current = previous; 567 if (!(current instanceof BigKeyPage)) { 568 569 pageSource.unpinPage(current); 570 current = null; 571 } else { 572 currentLength = ((BigKeyPage)current).keyLength; 573 } 574 } while ((current != null) && (currentLength == 0)); 575 576 return (BigKeyPage)current; 577 } 578 579 582 static BtreePage makeFirst(BtreePage root, BtreePageSource pageSource) 583 throws StorageException { 584 585 BtreePage newPage; 586 587 newPage = pageSource.newBigKeyPage(root.btree); 588 System.arraycopy(newPage.pageId, 0, root.nextPage, 0, 589 newPage.pageId.length); 590 System.arraycopy(root.pageId, 0, newPage.previousPage, 0, 591 newPage.pageId.length); 592 root.btree.setHasBigKeys(); 593 return newPage; 594 } 595 596 void dumpLevel(PrintWriter out) throws StorageException { 597 598 BigKeyPage current, next; 599 current = this; 600 do { 601 current.dumpPage(out); 602 next = current.getNextKeyStart(); 603 if (current != this) { 604 pageSource.unpinPage(current); 605 } 606 current = next; 607 } while (current != null); 608 } 609 610 public void dumpPageHeader(PrintWriter out) { 611 super.dumpPageHeader(out); 612 out.println("Key length: " + keyLength + "\n"); 613 } 614 615 public void dumpPageEntries(PrintWriter out) throws StorageException { 616 617 out.println("\nPage entries:\n\n"); 618 619 out.print(btree.keyInfo.fromBuffer(getKey(0)) + ", "); 620 out.println(btree.dataInfo.fromBuffer(getData(0))); 621 } 622 } 623 | Popular Tags |