예제 #1
0
 public void truncate(Session session) {
   if (trace.isDebugEnabled()) {
     trace.debug("{0} truncate", this);
   }
   store.logTruncate(session, tableData.getId());
   removeAllRows();
   if (tableData.getContainsLargeObject() && tableData.isPersistData()) {
     // unfortunately, the data is gone on rollback
     session.commit(false);
     database.getLobStorage().removeAllForTable(table.getId());
   }
   if (multiVersion) {
     sessionRowCount.clear();
   }
   tableData.setRowCount(0);
 }
예제 #2
0
  public PageDataIndex(
      RegularTable table,
      int id,
      IndexColumn[] columns,
      IndexType indexType,
      boolean create,
      Session session) {
    initBaseIndex(table, id, table.getName() + "_DATA", columns, indexType);
    RegularDatabase database = (RegularDatabase) this.database;
    this.multiVersion = database.isMultiVersion();

    // trace = database.getTrace(Trace.PAGE_STORE + "_di");
    // trace.setLevel(TraceSystem.DEBUG);
    if (multiVersion) {
      sessionRowCount = New.hashMap();
      isMultiVersion = true;
    } else {
      sessionRowCount = null;
    }
    tableData = table;
    this.store = database.getPageStore();
    store.addIndex(this);
    if (!database.isPersistent()) {
      throw DbException.throwInternalError(table.getName());
    }
    if (create) {
      rootPageId = store.allocatePage();
      store.addMeta(this, session);
      PageDataLeaf root = PageDataLeaf.create(this, rootPageId, PageData.ROOT);
      store.update(root);
    } else {
      rootPageId = store.getRootPageId(id);
      PageData root = getPage(rootPageId, 0);
      lastKey = root.getLastKey();
      rowCount = root.getRowCount();
    }
    if (trace.isDebugEnabled()) {
      trace.debug("{0} opened rows: {1}", this, rowCount);
    }
    table.setRowCount(rowCount);
    memoryPerPage = (Constants.MEMORY_PAGE_DATA + store.getPageSize()) >> 2;
  }
예제 #3
0
 public void add(Session session, Row row) {
   boolean retry = false;
   if (mainIndexColumn != -1) {
     row.setKey(row.getValue(mainIndexColumn).getLong());
   } else {
     if (row.getKey() == 0) {
       row.setKey((int) ++lastKey);
       retry = true;
     }
   }
   if (tableData.getContainsLargeObject()) {
     for (int i = 0, len = row.getColumnCount(); i < len; i++) {
       Value v = row.getValue(i);
       Value v2 = v.link(database, getId());
       if (v2.isLinked()) {
         session.unlinkAtCommitStop(v2);
       }
       if (v != v2) {
         row.setValue(i, v2);
       }
     }
   }
   // when using auto-generated values, it's possible that multiple
   // tries are required (specially if there was originally a primary key)
   if (trace.isDebugEnabled()) {
     trace.debug("{0} add {1}", getName(), row);
   }
   long add = 0;
   while (true) {
     try {
       addTry(session, row);
       break;
     } catch (DbException e) {
       if (e != fastDuplicateKeyException) {
         throw e;
       }
       if (!retry) {
         throw getNewDuplicateKeyException();
       }
       if (add == 0) {
         // in the first re-try add a small random number,
         // to avoid collisions after a re-start
         row.setKey((long) (row.getKey() + Math.random() * 10000));
       } else {
         row.setKey(row.getKey() + add);
       }
       add++;
     } finally {
       store.incrementChangeCount();
     }
   }
   lastKey = Math.max(lastKey, row.getKey());
 }
예제 #4
0
 public void remove(Session session, Row row) {
   if (tableData.getContainsLargeObject()) {
     for (int i = 0, len = row.getColumnCount(); i < len; i++) {
       Value v = row.getValue(i);
       if (v.isLinked()) {
         session.unlinkAtCommit(v);
       }
     }
   }
   if (trace.isDebugEnabled()) {
     trace.debug("{0} remove {1}", getName(), row);
   }
   if (rowCount == 1) {
     removeAllRows();
   } else {
     try {
       long key = row.getKey();
       PageData root = getPage(rootPageId, 0);
       root.remove(key);
       invalidateRowCount();
       rowCount--;
     } finally {
       store.incrementChangeCount();
     }
   }
   if (multiVersion) {
     // if storage is null, the delete flag is not yet set
     row.setDeleted(true);
     if (delta == null) {
       delta = New.hashSet();
     }
     boolean wasAdded = delta.remove(row);
     if (!wasAdded) {
       delta.add(row);
     }
     incrementRowCount(session.getId(), -1);
   }
   store.logAddOrRemoveRow(session, tableData.getId(), row, false);
 }
예제 #5
0
 private void addTry(Session session, Row row) {
   while (true) {
     PageData root = getPage(rootPageId, 0);
     int splitPoint = root.addRowTry(row);
     if (splitPoint == -1) {
       break;
     }
     if (trace.isDebugEnabled()) {
       trace.debug("{0} split", this);
     }
     long pivot = splitPoint == 0 ? row.getKey() : root.getKey(splitPoint - 1);
     PageData page1 = root;
     PageData page2 = root.split(splitPoint);
     int id = store.allocatePage();
     page1.setPageId(id);
     page1.setParentPageId(rootPageId);
     page2.setParentPageId(rootPageId);
     PageDataNode newRoot = PageDataNode.create(this, rootPageId, PageData.ROOT);
     newRoot.init(page1, pivot, page2);
     store.update(page1);
     store.update(page2);
     store.update(newRoot);
     root = newRoot;
   }
   row.setDeleted(false);
   if (multiVersion) {
     if (delta == null) {
       delta = New.hashSet();
     }
     boolean wasDeleted = delta.remove(row);
     if (!wasDeleted) {
       delta.add(row);
     }
     incrementRowCount(session.getId(), 1);
   }
   invalidateRowCount();
   rowCount++;
   store.logAddOrRemoveRow(session, tableData.getId(), row, true);
 }
예제 #6
0
 public double getCost(Session session, int[] masks) {
   long cost = 10 * (tableData.getRowCountApproximation() + Constants.COST_ROW_OFFSET);
   return cost;
 }