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()); }
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); }
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); }