📄 transactabletableimpl.java
字号:
_table.checkpoint(); } public void shutdown() throws AxionException { _table.shutdown(); } public void remount(File dir, boolean dataOnly) throws AxionException { _table.remount(dir, dataOnly); } public Row getRow(int id) throws AxionException { Integer Id = new Integer(id); ; if(_deletedRows.contains(id)) { return null; } else { Row row = (Row)_updatedRows.get(Id); if(null != row) { return row; } row = getInsertedRow(id); if(null != row) { return row; } return _table.getRow(id); } } public void applyInserts(Iterator rows) throws AxionException { _table.applyInserts(rows); } public void applyDeletes(IntIterator rowids) throws AxionException { _table.applyDeletes(rowids); } public void applyUpdates(Iterator rows) throws AxionException { _table.applyUpdates(rows); } public void commit() throws AxionException { if(_log.isDebugEnabled()) { _log.debug("commit() " + this); } assertOpen(); if(hasDeferredConstraint()) { for(Iterator iter = _insertedRows.iterator();iter.hasNext(); ) { Row row = (Row)iter.next(); RowEvent event = new RowInsertedEvent(this,null,row); checkConstraints(event,true); } for(int i=0;i<_deletedRows.size();i++) { int id = _deletedRows.get(i); Row row = _table.getRow(id); RowEvent event = new RowDeletedEvent(this,row,null); checkConstraints(event,true); } for(Iterator iter = _updatedRows.values().iterator();iter.hasNext(); ) { Row row = (Row)iter.next(); Row oldrow = _table.getRow(row.getIdentifier()); RowEvent event = new RowUpdatedEvent(this,oldrow,row); checkConstraints(event,true); } } _state = Transaction.STATE_COMMITTED; } public void rollback() throws AxionException { if(_log.isDebugEnabled()) { _log.debug("rollback() " + this); } assertOpen(); for(int i=0;i<_reservedRowIds.size();i++) { freeRowId(_reservedRowIds.get(i)); } _reservedRowIds = null; _table = null; _insertedRows = null; _updatedRows = null; _deletedRows = null; _state = Transaction.STATE_ABORTED; } public void apply() throws AxionException { if(_log.isDebugEnabled()) { _log.debug("apply() " + this); } assertCommitted(); // apply deletes if(!_deletedRows.isEmpty()) { for(int i=0;i<_deletedRows.size();i++) { Row deleted = _table.getRow(_deletedRows.get(i)); RowEvent event = new RowDeletedEvent(_table,deleted,null); for(Iterator iter = _table.getIndices();iter.hasNext();) { Index index = (Index)(iter.next()); index.rowDeleted(event); } } _table.applyDeletes(_deletedRows.iterator()); } // apply updates if(!_updatedRows.isEmpty()) { for(Iterator iter = _updatedRows.values().iterator(); iter.hasNext();) { Row newrow = (Row)(iter.next()); Row oldrow = _table.getRow(newrow.getIdentifier()); RowEvent event = new RowUpdatedEvent(_table,oldrow,newrow); for(Iterator indexIter = _table.getIndices();indexIter.hasNext();) { Index index = (Index)(indexIter.next()); index.rowUpdated(event); } } _table.applyUpdates(_updatedRows.values().iterator()); } // apply inserts if(!_insertedRows.isEmpty()) { for(Iterator iter = _insertedRows.iterator(); iter.hasNext();) { Row row= (Row)(iter.next()); RowEvent event = new RowInsertedEvent(_table,null,row); for(Iterator indexIter = _table.getIndices();indexIter.hasNext();) { Index index = (Index)(indexIter.next()); index.rowInserted(event); } } _table.applyInserts(_insertedRows.iterator()); } _state = Transaction.STATE_APPLIED; } public TransactableTable makeTransactableTable() { return new TransactableTableImpl(this); } protected void checkConstraints(RowEvent event) throws AxionException { checkConstraints(event,false); } protected void checkConstraints(RowEvent event, boolean deferred) throws AxionException { for(Iterator iter = getConstraints();iter.hasNext();) { Constraint c = (Constraint)iter.next(); if(c.isDeferred() == deferred) { if(!c.evaluate(event)) { throw new ConstraintViolationException(c); } } } } protected boolean hasDeferredConstraint() { for(Iterator iter = getConstraints();iter.hasNext();) { Constraint c = (Constraint)iter.next(); if(c.isDeferred()) { return true; } } return false; } void deleteRow(Row row) throws AxionException { // by construction, this method should never be // called for a row that only exists in _insertedRows, // so we'll ignore that case RowEvent event = new RowDeletedEvent(this,row,null); checkConstraints(event); // add the row to our list of deleted rows if(!_deletedRows.contains(row.getIdentifier())) { _deletedRows.add(row.getIdentifier()); } // delete from _updatedRows, if it's in there _updatedRows.remove(new Integer(row.getIdentifier())); publishEvent(event); } void updateRow(Row oldrow, Row newrow) throws AxionException { newrow.setIdentifier(oldrow.getIdentifier()); RowEvent event = new RowUpdatedEvent(this,oldrow,newrow); checkConstraints(event); _updatedRows.put(new Integer(oldrow.getIdentifier()),newrow); publishEvent(event); } private Row getInsertedRow(int id) { for(int i=0;i<_insertedRows.size();i++) { Row row = (Row)_insertedRows.get(i); if(row.getIdentifier() == id) { return row; } } return null; } private void assertOpen() throws AxionException { if(Transaction.STATE_OPEN != _state) { throw new AxionException("Already committed or rolled back [" + _state + "]."); } } private void assertCommitted() throws AxionException { if(Transaction.STATE_COMMITTED != _state) { throw new AxionException("Not committed [" + _state + "]."); } } /** * Overrides {@link #remove} and {@link #set} to apply them to the * current transaction. */ private class TransactableTableRowIterator extends DelegatingRowIterator { public TransactableTableRowIterator(RowIterator iter) { super(iter); } public void remove() throws AxionException { deleteRow(current()); } public void set(Row row) throws AxionException { updateRow(current(),row); } } /** * Filters out rows that have been deleted in the current transaction. */ private class ExcludeDeleted extends AbstractAcceptingRowIterator { public ExcludeDeleted(RowIterator iter) { super(iter); } protected boolean acceptable(int rowindex, Row row) throws AxionException { return !(_deletedRows.contains(row.getIdentifier())); } } /** * Filters out rows that have been updated in the current transaction. */ private class ExcludeUpdated extends AbstractAcceptingRowIterator { public ExcludeUpdated(RowIterator iter) { super(iter); } protected boolean acceptable(int rowindex, Row row) throws AxionException { return !(_updatedRows.containsKey(new Integer(row.getIdentifier()))); } } /** * Transforms rows that have been updated within the current transaction. */ private class TransformUpdated extends TransformingRowIterator { public TransformUpdated(RowIterator iter) { super(iter); } public void remove() throws AxionException { deleteRow(current()); } public void set(Row row) throws AxionException { updateRow(current(),row); } protected Row transform(Row row) { Row updated = (Row)_updatedRows.get(new Integer(row.getIdentifier())); if(null != updated) { return updated; } else { return row; } } } private RowIterator excludeDeletedTransformUpdated(RowIterator base) { if(null == base) { return null; } else { return new TransactableTableRowIterator( new ExcludeDeleted( new TransformUpdated(base))); } } private RowIterator excludeDeletedAndUpdated(RowIterator base) { if(null == base) { return null; } else { return new TransactableTableRowIterator( new ExcludeDeleted( new ExcludeUpdated(base))); } } private class InsertedRowIterator extends ListIteratorRowIterator { public InsertedRowIterator(ListIterator iter) { super(iter); } public void remove() { if(_reservedRowIds.removeElement(current().getIdentifier())) { _table.freeRowId(current().getIdentifier()); } super.remove(); } } private boolean hasUpdates() { return !(_updatedRows.isEmpty()); } private boolean hasDeletes() { return !(_deletedRows.isEmpty()); } private boolean hasInserts() { return !(_insertedRows.isEmpty()); } Table _table = null; /** {@link IntArrayList} of row identifiers that have been reserved from my underlying table. */ IntList _reservedRowIds = new ArrayIntList(); /** {@link List} of {@link Row}s that have been inserted. */ private List _insertedRows = new ArrayList(); /** {@link Map} of {@link Row}s that have been updated, keyed by row identifier. */ Map _updatedRows = new HashMap(); /** {@link IntArrayList} of row identifiers that have been deleted. */ IntList _deletedRows = new ArrayIntList(); /** My current state. */ private int _state = Transaction.STATE_OPEN; private static Log _log = LogFactory.getLog(TransactableTableImpl.class);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -