예제 #1
0
 public ChangeEnumerator(TableSnapshot <TRecord> table, List <int> version)
 {
     // assuming version is sorted
     this.table      = table.table;
     this.newVersion = version[version.Count - 1];
     this.oldVersion = version[0];
     this.MergeChanges(version);
     this.enumerator = this.action.GetEnumerator();
 }
예제 #2
0
 /// <summary>
 /// Constructs the table
 /// </summary>
 /// <param name="store"></param>
 /// <param name="name"></param>
 /// <param name="fields"></param>
 public TableSnapshot(StoreSnapshot store, string name, params IField <TRecord>[] fields)
 {
     if (fields == null)
     {
         throw new ArgumentNullException(nameof(fields));
     }
     this.StoreSnapshot = store ?? throw new ArgumentNullException(nameof(store));
     this.table         = new SnapTable <TRecord>(store.SnapStore, name, 0, fields, true);
     this.StoreSnapshot.Add(this, this.table);
 }
예제 #3
0
        /// <summary>
        /// Deletes row.
        /// </summary>
        /// <param name="rowId"></param>
        public void Delete(RowId rowId)
        {
            Debug.Assert(0 <= rowId.Value && rowId.Value < this.table.Count, "broken rowId");
            this.ValidateModification();
            ValueList <Row> .Address address = this.table.ItemAddress(rowId.Value);
            SnapTable <TRecord> .ValidateModification(ref address);

            this.PushToLog(ref address.Page[address.Index], rowId);
            // if the row was inserted in this transaction, then after deletion it will be invalid. so just ignore it in all future operations
            address.Page[address.Index].IsDeleted = true;
        }
예제 #4
0
        private static bool IsEmpty(SnapTable <TRecord> table, int version)
        {
            int count = table.Count(version);

            for (int i = 0; i < count; i++)
            {
                if (!table.IsDeleted(new RowId(i), version, false))
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #5
0
 public BTree(SnapStore store, string name, IComparer <TField> comparer)
 {
     this.fields    = Node.CreateFields(comparer, out this.countField, out this.isLeafField, out this.keyFields, out this.childFields);
     this.MinDegree = this.keyFields.Length / 2;
     Debug.Assert(1 < this.MinDegree && this.MinDegree * 2 + 1 == this.keyFields.Length && this.keyFields.Length + 1 == this.childFields.Length,
                  "Wrong field definition"
                  );
     this.table = new SnapTable <Node>(store, name, 1, this.fields, false);
     this.data  = new IntArray(store, name + "~Data~", 1);
                 #if ValidateTree
     this.Validate();
                 #endif
 }
예제 #6
0
        /// <summary>
        /// Sets entire structure.
        /// </summary>
        /// <param name="rowId"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool SetData(RowId rowId, ref TRecord data)
        {
            Debug.Assert(0 <= rowId.Value && rowId.Value < this.table.Count, "broken rowId");
            this.ValidateModification();
            ValueList <Row> .Address address = this.table.ItemAddress(rowId.Value);
            SnapTable <TRecord> .ValidateModification(ref address);

            if (TableSnapshot <TRecord> .Compare(this.Fields, ref address.Page[address.Index].Data, ref data) != 0)
            {
                this.PushToLog(ref address.Page[address.Index], rowId);
                address.Page[address.Index].Data = data;
                Debug.Assert(TableSnapshot <TRecord> .Compare(this.Fields, ref address.Page[address.Index].Data, ref data) == 0, "Assignment or comparison failed");
                return(true);
            }
            return(false);
        }
예제 #7
0
        /// <summary>
        /// Updates field of the row
        /// </summary>
        /// <typeparam name="TField"></typeparam>
        /// <param name="rowId"></param>
        /// <param name="field"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetField <TField>(RowId rowId, IField <TRecord, TField> field, TField value)
        {
            Debug.Assert(0 <= rowId.Value && rowId.Value < this.table.Count, "broken rowId");
            this.ValidateModification();
            // It is only possible to set value via basic fields defined on table.
            this.ValidateField(field);
            ValueList <Row> .Address address = this.table.ItemAddress(rowId.Value);
            SnapTable <TRecord> .ValidateModification(ref address);

            if (field.Compare(field.GetValue(ref address.Page[address.Index].Data), value) != 0)
            {
                this.PushToLog(ref address.Page[address.Index], rowId);
                field.SetValue(ref address.Page[address.Index].Data, value);
                Debug.Assert(field.Compare(field.GetValue(ref address.Page[address.Index].Data), value) == 0, "Assignment or comparison failed");
                return(true);
            }
            return(false);
        }
예제 #8
0
 public Unique(SnapStore store, string name, IComparer <TField> comparer, float loadFactor)
 {
     if (!(loadFactor >= 0.1f && loadFactor <= 1.0f))
     {
         throw new ArgumentOutOfRangeException("loadFactor");
     }
     this.valueField = new ValueField(comparer);
     this.table      = new SnapTable <Bucket>(store, name, Unique <TField> .MinSize,
                                              new IField <Bucket>[] { this.valueField, RowIdField.Field, HashField.Field, CollisionField.Field },
                                              false
                                              );
     // allocate 3 int values:
     // [0] - is the count of items inserted
     // [1] - is known size of the bucket store which is different from table size, as rollbacks or undo's will delete inserted rows
     // [2] - is occupancy - total number of collision bits set
     this.variables  = new IntArray(store, name + "~Variables~", 3);
     this.loadFactor = loadFactor;
 }
예제 #9
0
            public ChangeEnumerator(SnapTable <TRecord> table, int version, bool forRollback)
            {
                this.table       = table;
                this.forRollback = forRollback;
                int pointIndex = this.table.snap.Count - 1;

                ValueList <Snap> .Address snapAddress = this.table.snap.ItemAddress(pointIndex);
                while (version < snapAddress.Page[snapAddress.Index].Version)
                {
                    snapAddress = this.table.snap.ItemAddress(--pointIndex);
                }
                if (version != snapAddress.Page[snapAddress.Index].Version)
                {
                    throw new ArgumentOutOfRangeException(nameof(version));
                }
                this.newVersion  = snapAddress.Page[snapAddress.Index];
                snapAddress      = this.table.snap.ItemAddress(pointIndex - 1);
                this.oldVersion  = snapAddress.Page[snapAddress.Index];
                this.changeIndex = -1;
            }
예제 #10
0
 public UniqueIndex(SnapTable <TRecord> table, string name, IField <TRecord, TField> field)
 {
     this.table  = table;
     this.field  = field;
     this.unique = new Unique <TField>(table.SnapStore, name, field);
 }
예제 #11
0
 public RangeIndex(SnapTable <TRecord> table, string name, IField <TRecord, TField> field)
 {
     this.table = table;
     this.field = field;
     this.tree  = new BTree <TField>(table.SnapStore, name, field);
 }
예제 #12
0
 public UniquePseudoIndex(SnapTable <TRecord> table)
 {
     this.table = table;
 }
예제 #13
0
 /// <summary>
 /// Copy constructor
 /// </summary>
 /// <param name="storeSnapshot"></param>
 /// <param name="table"></param>
 internal TableSnapshot(StoreSnapshot storeSnapshot, SnapTable <TRecord> table)
 {
     this.StoreSnapshot = storeSnapshot;
     this.table         = table;
     this.StoreSnapshot.Add(this, this.table);
 }
예제 #14
0
 public IntArray(SnapStore store, string name, int size)
 {
     this.table = new SnapTable <int>(store, name, size, new IField <int>[] { IntArray.Field }, false);
 }