1 /* Copyright (C) 2004 - 2009 Versant Inc. http://www.db4o.com */ 2 3 using System; 4 using Db4objects.Db4o.Foundation; 5 using Db4objects.Db4o.Internal; 6 using Db4objects.Db4o.Internal.Btree; 7 8 namespace Db4objects.Db4o.Internal.Btree 9 { 10 public abstract class BTreeUpdate : BTreePatch 11 { 12 protected Db4objects.Db4o.Internal.Btree.BTreeUpdate _next; 13 BTreeUpdate(Transaction transaction, object obj)14 public BTreeUpdate(Transaction transaction, object obj) : base(transaction, obj) 15 { 16 } 17 HasNext()18 protected virtual bool HasNext() 19 { 20 return _next != null; 21 } 22 ForTransaction(Transaction trans)23 public override BTreePatch ForTransaction(Transaction trans) 24 { 25 if (_transaction == trans) 26 { 27 return this; 28 } 29 if (_next == null) 30 { 31 return null; 32 } 33 return _next.ForTransaction(trans); 34 } 35 RemoveFor(Transaction trans )36 public virtual Db4objects.Db4o.Internal.Btree.BTreeUpdate RemoveFor(Transaction trans 37 ) 38 { 39 if (_transaction == trans) 40 { 41 return _next; 42 } 43 if (_next == null) 44 { 45 return this; 46 } 47 return _next.RemoveFor(trans); 48 } 49 Append(Db4objects.Db4o.Internal.Btree.BTreeUpdate patch)50 public virtual void Append(Db4objects.Db4o.Internal.Btree.BTreeUpdate patch) 51 { 52 if (_transaction == patch._transaction) 53 { 54 // don't allow two patches for the same transaction 55 throw new ArgumentException(); 56 } 57 if (!HasNext()) 58 { 59 _next = patch; 60 } 61 else 62 { 63 _next.Append(patch); 64 } 65 } 66 ApplyKeyChange(object obj)67 protected virtual void ApplyKeyChange(object obj) 68 { 69 _object = obj; 70 if (HasNext()) 71 { 72 _next.ApplyKeyChange(obj); 73 } 74 } 75 Committed(BTree btree)76 protected abstract void Committed(BTree btree); 77 Commit(Transaction trans, BTree btree, BTreeNode node)78 public override object Commit(Transaction trans, BTree btree, BTreeNode node) 79 { 80 Db4objects.Db4o.Internal.Btree.BTreeUpdate patch = (Db4objects.Db4o.Internal.Btree.BTreeUpdate 81 )ForTransaction(trans); 82 if (patch is BTreeCancelledRemoval) 83 { 84 object obj = patch.GetCommittedObject(); 85 ApplyKeyChange(obj); 86 } 87 else 88 { 89 if (patch is BTreeRemove) 90 { 91 RemovedBy(trans, btree, node); 92 patch.Committed(btree); 93 return No4.Instance; 94 } 95 } 96 return InternalCommit(trans, btree); 97 } 98 InternalCommit(Transaction trans, BTree btree)99 protected object InternalCommit(Transaction trans, BTree btree) 100 { 101 if (_transaction == trans) 102 { 103 Committed(btree); 104 if (HasNext()) 105 { 106 return _next; 107 } 108 return GetCommittedObject(); 109 } 110 if (HasNext()) 111 { 112 SetNextIfPatch(_next.InternalCommit(trans, btree)); 113 } 114 return this; 115 } 116 SetNextIfPatch(object newNext)117 private void SetNextIfPatch(object newNext) 118 { 119 if (newNext is Db4objects.Db4o.Internal.Btree.BTreeUpdate) 120 { 121 _next = (Db4objects.Db4o.Internal.Btree.BTreeUpdate)newNext; 122 } 123 else 124 { 125 _next = null; 126 } 127 } 128 GetCommittedObject()129 protected abstract object GetCommittedObject(); 130 Rollback(Transaction trans, BTree btree)131 public override object Rollback(Transaction trans, BTree btree) 132 { 133 if (_transaction == trans) 134 { 135 if (HasNext()) 136 { 137 return _next; 138 } 139 return GetObject(); 140 } 141 if (HasNext()) 142 { 143 SetNextIfPatch(_next.Rollback(trans, btree)); 144 } 145 return this; 146 } 147 Key(Transaction trans)148 public override object Key(Transaction trans) 149 { 150 BTreePatch patch = ForTransaction(trans); 151 if (patch == null) 152 { 153 return GetObject(); 154 } 155 if (patch.IsRemove()) 156 { 157 return No4.Instance; 158 } 159 return patch.GetObject(); 160 } 161 ReplacePatch(BTreePatch patch, Db4objects.Db4o.Internal.Btree.BTreeUpdate update)162 public virtual Db4objects.Db4o.Internal.Btree.BTreeUpdate ReplacePatch(BTreePatch 163 patch, Db4objects.Db4o.Internal.Btree.BTreeUpdate update) 164 { 165 if (patch == this) 166 { 167 update._next = _next; 168 return update; 169 } 170 if (_next == null) 171 { 172 throw new InvalidOperationException(); 173 } 174 _next = _next.ReplacePatch(patch, update); 175 return this; 176 } 177 RemovedBy(Transaction trans, BTree btree, BTreeNode node)178 public virtual void RemovedBy(Transaction trans, BTree btree, BTreeNode node) 179 { 180 if (trans != _transaction) 181 { 182 AdjustSizeOnRemovalByOtherTransaction(btree, node); 183 } 184 if (HasNext()) 185 { 186 _next.RemovedBy(trans, btree, node); 187 } 188 } 189 AdjustSizeOnRemovalByOtherTransaction(BTree btree, BTreeNode node)190 protected abstract void AdjustSizeOnRemovalByOtherTransaction(BTree btree, BTreeNode 191 node); 192 SizeDiff(Transaction trans)193 public override int SizeDiff(Transaction trans) 194 { 195 Db4objects.Db4o.Internal.Btree.BTreeUpdate patchForTransaction = (Db4objects.Db4o.Internal.Btree.BTreeUpdate 196 )ForTransaction(trans); 197 if (patchForTransaction == null) 198 { 199 return 1; 200 } 201 return patchForTransaction.SizeDiff(); 202 } 203 SizeDiff()204 protected abstract int SizeDiff(); 205 } 206 } 207