Exemplo n.º 1
0
        public static bool TestCommitClash(this ITableEventRegistry registry, ITableEventRegistry other, out RowRemoveConflict conflict)
        {
            lock (registry) {
                // Very nasty search here...
                foreach (var rowEvent in registry.OfType <TableRowEvent>())
                {
                    if (rowEvent.EventType == TableRowEventType.Remove)
                    {
                        var rowNum = rowEvent.RowNumber;
                        foreach (var otherRowEvent in other.OfType <TableRowEvent>())
                        {
                            if (otherRowEvent.RowNumber == rowNum &&
                                otherRowEvent.EventType == TableRowEventType.Remove)
                            {
                                conflict = new RowRemoveConflict(registry.TableId, rowNum);

                                return(true);
                            }
                        }
                    }
                }

                conflict = new RowRemoveConflict();
                return(false);
            }
        }
Exemplo n.º 2
0
        public static long[] GetAddedRows(this ITableEventRegistry registry)
        {
            lock (registry) {
                var list = new List <long>();

                foreach (var tableEvent in registry.OfType <TableRowEvent>())
                {
                    var eventType = tableEvent.EventType;
                    if (eventType == TableRowEventType.Add ||
                        eventType == TableRowEventType.UpdateAdd)
                    {
                        list.Add(tableEvent.RowNumber);
                    }
                    else if (eventType == TableRowEventType.Remove ||
                             eventType == TableRowEventType.UpdateRemove)
                    {
                        var index = list.IndexOf(tableEvent.RowNumber);
                        if (index != -1)
                        {
                            list.RemoveAt(index);
                        }
                    }
                }

                return(list.ToArray());
            }
        }
Exemplo n.º 3
0
        public static long[] GetRemovedRows(this ITableEventRegistry registry)
        {
            lock (registry) {
                var list = new List <long>();

                foreach (var tableEvent in registry.OfType <TableRowEvent>())
                {
                    if (tableEvent.EventType == TableRowEventType.Remove ||
                        tableEvent.EventType == TableRowEventType.UpdateRemove)
                    {
                        list.Add(tableEvent.RowNumber);
                    }
                }

                return(list.ToArray());
            }
        }
Exemplo n.º 4
0
        internal void RollbackTransactionChange(ITableEventRegistry registry)
        {
            lock (this) {
                // ASSERT: Can't do this is source is Read only.
                if (IsReadOnly)
                {
                    throw new InvalidOperationException("Can't rollback transaction journal, table is Read only.");
                }

                // Any rows added in the journal are marked as committed deleted and the
                // journal is then discarded.

                try {
                    // Mark all rows in the data_store as appropriate to the changes.
                    foreach (var tableEvent in registry)
                    {
                        if (tableEvent is TableRowEvent)
                        {
                            var rowEvent = (TableRowEvent)tableEvent;

                            if (rowEvent.EventType == TableRowEventType.Add)
                            {
                                var oldState = WriteRecordState(rowEvent.RowNumber, RecordState.CommittedRemoved);

                                if (oldState != RecordState.Uncommitted)
                                {
                                    WriteRecordState(rowEvent.RowNumber, oldState);

                                    throw new InvalidOperationException($"Record {rowEvent.RowNumber} was not in an uncommitted state.");
                                }

                                GC.DeleteRow(rowEvent.RowNumber);
                            }
                        }
                    }
                } catch (IOException e) {
                    throw new InvalidOperationException("IO Error: " + e.Message, e);
                }
            }
        }
Exemplo n.º 5
0
        internal void CommitTransactionChange(long commitId, ITableEventRegistry change, IRowIndexSet indexSet)
        {
            lock (this) {
                // ASSERT: Can't do this if source is Read only.
                if (IsReadOnly)
                {
                    throw new InvalidOperationException("Can't commit transaction journal, table is Read only.");
                }

                // CHECK!
                // TODO: change.CommitId = commitId;

                try {
                    // Add this registry to the multi version table indices log
                    Registries.AddRegistry(change);

                    // Write the modified index set to the index store
                    // (Updates the index file)
                    CommitIndexSet(indexSet);

                    // Update the state of the committed added data to the file system.
                    // (Updates data to the allocation file)
                    //
                    // ISSUE: This can add up to a lot of changes to the allocation file and
                    //   the runtime could potentially be terminated in the middle of
                    //   the update.  If an interruption happens the allocation information
                    //   may be incorrectly flagged.  The type of corruption this would
                    //   result in would be;
                    //   + From an 'update' the updated record may disappear.
                    //   + From a 'delete' the deleted record may not delete.
                    //   + From an 'insert' the inserted record may not insert.
                    //
                    // Note, the possibility of this type of corruption occuring has been
                    // minimized as best as possible given the current architecture.
                    // Also note that is not possible for a table file to become corrupted
                    // beyond recovery from this issue.

                    foreach (var entry in change)
                    {
                        if (entry is TableRowEvent)
                        {
                            var rowEvent = (TableRowEvent)entry;
                            var rowIndex = rowEvent.RowNumber;

                            if (rowEvent.EventType == TableRowEventType.Add)
                            {
                                // Record commit added
                                var oldType = WriteRecordState(rowIndex, RecordState.CommittedAdded);

                                // Check the record was in an uncommitted state before we changed
                                // it.
                                if (oldType != RecordState.Uncommitted)
                                {
                                    WriteRecordState(rowIndex, oldType);
                                    throw new InvalidOperationException($"Record {rowIndex} of table {TableName} was not in an uncommitted state!");
                                }
                            }
                            else if (rowEvent.EventType == TableRowEventType.Remove)
                            {
                                // Record commit removed
                                var oldType = WriteRecordState(rowIndex, RecordState.CommittedRemoved);

                                // Check the record was in an added state before we removed it.
                                if (oldType != RecordState.CommittedAdded)
                                {
                                    WriteRecordState(rowIndex, oldType);
                                    throw new InvalidOperationException($"Record {rowIndex} of table {TableName} was not in an added state!");
                                }

                                // Notify collector that this row has been marked as deleted.
                                GC.DeleteRow(rowIndex);
                            }
                        }
                    }
                } catch (IOException e) {
                    throw new InvalidOperationException("IO Error: " + e.Message, e);
                }
            }
        }
Exemplo n.º 6
0
 public void Rollback(ITableEventRegistry registry)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 7
0
 public IMutableTable GetMutableTable(ITransaction transaction, ITableEventRegistry registry)
 {
     throw new NotImplementedException();
 }