Beispiel #1
0
 public long getRowCount(Session session) {
   if (multiVersion) {
     Integer i = sessionRowCount.get(session.getId());
     long count = i == null ? 0 : i.intValue();
     count += rowCount;
     count -= rowCountDiff;
     return count;
   }
   return rowCount;
 }
Beispiel #2
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());
 }
Beispiel #3
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);
 }
Beispiel #4
0
 /**
  * Flush the current value, including the margin, to disk.
  *
  * @param session the session
  */
 public synchronized void flush(Session session) {
   Session sysSession = database.getSystemSession();
   if (session == null || !database.isSysTableLocked()) {
     // this session may not lock the sys table (except if it already has locked it)
     // because it must be committed immediately
     // otherwise other threads can not access the sys table.
     session = sysSession;
   }
   synchronized (session) {
     // just for this case, use the value with the margin for the script
     long realValue = value;
     try {
       value = valueWithMargin;
       database.update(session, this);
     } finally {
       value = realValue;
     }
     if (session == sysSession) {
       // if the system session is used,
       // the transaction must be committed immediately
       sysSession.commit(false);
     }
   }
 }
Beispiel #5
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);
 }
Beispiel #6
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);
 }