Esempio n. 1
0
 /**
  * Get the row at the given index.
  *
  * @param at the index
  * @return the row
  */
 Row getRowAt(int at) {
   Row r = rows[at];
   if (r == null) {
     if (firstOverflowPageId == 0) {
       r = readRow(data, offsets[at], columnCount);
     } else {
       if (rowRef != null) {
         r = rowRef.get();
         if (r != null) {
           return r;
         }
       }
       PageStore store = index.getPageStore();
       Data buff = store.createData();
       int pageSize = store.getPageSize();
       int offset = offsets[at];
       buff.write(data.getBytes(), offset, pageSize - offset);
       int next = firstOverflowPageId;
       do {
         PageDataOverflow page = index.getPageOverflow(next);
         next = page.readInto(buff);
       } while (next != 0);
       overflowRowSize = pageSize + buff.length();
       r = readRow(buff, 0, columnCount);
     }
     r.setKey(keys[at]);
     if (firstOverflowPageId != 0) {
       rowRef = new SoftReference<Row>(r);
     } else {
       rows[at] = r;
       memoryChange(true, r);
     }
   }
   return r;
 }
Esempio n. 2
0
 protected void remapChildren(int old) {
   if (firstOverflowPageId == 0) {
     return;
   }
   PageDataOverflow overflow = index.getPageOverflow(firstOverflowPageId);
   overflow.setParentPageId(getPos());
   index.getPageStore().update(overflow);
 }
Esempio n. 3
0
 private void freeOverflow() {
   if (firstOverflowPageId != 0) {
     int next = firstOverflowPageId;
     do {
       PageDataOverflow page = index.getPageOverflow(next);
       page.free();
       next = page.getNextOverflow();
     } while (next != 0);
   }
 }
Esempio n. 4
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;
 }