示例#1
0
 private void removeRow(int i) {
   index.getPageStore().logUndo(this, data);
   written = false;
   changeCount = index.getPageStore().getChangeCount();
   if (!optimizeUpdate) {
     readAllRows();
   }
   Row r = getRowAt(i);
   if (r != null) {
     memoryChange(false, r);
   }
   entryCount--;
   if (entryCount < 0) {
     DbException.throwInternalError();
   }
   if (firstOverflowPageId != 0) {
     start -= 4;
     freeOverflow();
     firstOverflowPageId = 0;
     overflowRowSize = 0;
     rowRef = null;
   }
   int keyOffsetPairLen = 2 + Data.getVarLongLen(keys[i]);
   int startNext = i > 0 ? offsets[i - 1] : index.getPageStore().getPageSize();
   int rowLength = startNext - offsets[i];
   if (optimizeUpdate) {
     if (writtenData) {
       byte[] d = data.getBytes();
       int dataStart = offsets[entryCount];
       System.arraycopy(d, dataStart, d, dataStart + rowLength, offsets[i] - dataStart);
       Arrays.fill(d, dataStart, dataStart + rowLength, (byte) 0);
     }
   } else {
     int clearStart = offsets[entryCount];
     Arrays.fill(data.getBytes(), clearStart, clearStart + rowLength, (byte) 0);
   }
   start -= keyOffsetPairLen;
   offsets = remove(offsets, entryCount + 1, i);
   add(offsets, i, entryCount, rowLength);
   keys = remove(keys, entryCount + 1, i);
   rows = remove(rows, entryCount + 1, i);
 }
示例#2
0
 int addRowTry(Row row) {
   index.getPageStore().logUndo(this, data);
   int rowLength = getRowLength(row);
   int pageSize = index.getPageStore().getPageSize();
   int last = entryCount == 0 ? pageSize : offsets[entryCount - 1];
   int keyOffsetPairLen = 2 + Data.getVarLongLen(row.getKey());
   if (entryCount > 0 && last - rowLength < start + keyOffsetPairLen) {
     int x = findInsertionPoint(row.getKey());
     if (entryCount > 1) {
       if (entryCount < 5) {
         // required, otherwise the index doesn't work correctly
         return entryCount / 2;
       }
       if (index.isSortedInsertMode()) {
         return x < 2 ? 1 : x > entryCount - 1 ? entryCount - 1 : x;
       }
       // split near the insertion point to better fill pages
       // split in half would be:
       // return entryCount / 2;
       int third = entryCount / 3;
       return x < third ? third : x >= 2 * third ? 2 * third : x;
     }
     return x;
   }
   index.getPageStore().logUndo(this, data);
   int x;
   if (entryCount == 0) {
     x = 0;
   } else {
     if (!optimizeUpdate) {
       readAllRows();
     }
     x = findInsertionPoint(row.getKey());
   }
   written = false;
   changeCount = index.getPageStore().getChangeCount();
   last = x == 0 ? pageSize : offsets[x - 1];
   int offset = last - rowLength;
   start += keyOffsetPairLen;
   offsets = insert(offsets, entryCount, x, offset);
   add(offsets, x + 1, entryCount + 1, -rowLength);
   keys = insert(keys, entryCount, x, row.getKey());
   rows = insert(rows, entryCount, x, row);
   entryCount++;
   index.getPageStore().update(this);
   if (optimizeUpdate) {
     if (writtenData && offset >= start) {
       byte[] d = data.getBytes();
       int dataStart = offsets[entryCount - 1] + rowLength;
       int dataEnd = offsets[x];
       System.arraycopy(d, dataStart, d, dataStart - rowLength, dataEnd - dataStart + rowLength);
       data.setPos(dataEnd);
       for (int j = 0; j < columnCount; j++) {
         data.writeValue(row.getValue(j));
       }
     }
   }
   if (offset < start) {
     writtenData = false;
     if (entryCount > 1) {
       DbException.throwInternalError();
     }
     // need to write the overflow page id
     start += 4;
     int remaining = rowLength - (pageSize - start);
     // fix offset
     offset = start;
     offsets[x] = offset;
     int previous = getPos();
     int dataOffset = pageSize;
     int page = index.getPageStore().allocatePage();
     firstOverflowPageId = page;
     this.overflowRowSize = pageSize + rowLength;
     writeData();
     // free up the space used by the row
     Row r = rows[0];
     rowRef = new SoftReference<Row>(r);
     rows[0] = null;
     Data all = index.getPageStore().createData();
     all.checkCapacity(data.length());
     all.write(data.getBytes(), 0, data.length());
     data.truncate(index.getPageStore().getPageSize());
     do {
       int type, size, next;
       if (remaining <= pageSize - PageDataOverflow.START_LAST) {
         type = Page.TYPE_DATA_OVERFLOW | Page.FLAG_LAST;
         size = remaining;
         next = 0;
       } else {
         type = Page.TYPE_DATA_OVERFLOW;
         size = pageSize - PageDataOverflow.START_MORE;
         next = index.getPageStore().allocatePage();
       }
       PageDataOverflow overflow =
           PageDataOverflow.create(
               index.getPageStore(), page, type, previous, next, all, dataOffset, size);
       index.getPageStore().update(overflow);
       dataOffset += size;
       remaining -= size;
       previous = page;
       page = next;
     } while (remaining > 0);
   }
   if (rowRef == null) {
     memoryChange(true, row);
   } else {
     memoryChange(true, null);
   }
   return -1;
 }