/// <summary> /// 11/28/2011 /// Initializes a new instance of the <see cref = "TransactionManager" /> class. /// </summary> /// <remarks> /// Side effects: /// 1. currentTimeStamp is set to 0 /// 2. All the data structures are initialized /// 3. All sites are initialized /// </remarks> public TransactionManager() { currentTimeStamp = 0; committedTransactions = new List<Transaction>(); activeTransactions = new Dictionary<int, Transaction>(); waitingTransactions = new Dictionary<int, Transaction>(); abortedTransactions = new Dictionary<int, string>(); waitingOps = new List<Operation>(); sites = new Dictionary<int, Site>(NumberOfSites); results = new List<Result>(); for (int i = 1; i <= NumberOfSites; i++) { sites[i] = new Site(i); } }
public void FailedTest() { Site target = new Site(); bool expected = false; bool actual; actual = target.Failed(); Assert.AreEqual(expected, actual); target.Fail(1); actual = target.Failed(); expected = true; Assert.AreEqual(expected, actual); actual = target.Failed(); expected = true; Assert.AreEqual(expected, actual); }
public void GetFirstFailureTest() { Site target = new Site(1); int beginning = 0; int expected = 1; int? actual; actual = target.GetFirstFailureSinceAccess(beginning); Assert.IsNull(actual); target.Fail(1); target.Fail(4); target.Fail(2); target.Fail(10); target.Fail(7); actual = target.GetFirstFailureSinceAccess(beginning); Assert.AreEqual(expected, actual); expected = 4; beginning = 3; actual = target.GetFirstFailureSinceAccess(beginning); Assert.AreEqual(expected, actual); expected = 10; beginning = 11; actual = target.GetFirstFailureSinceAccess(beginning); Assert.IsNull(actual); }
public void TickTest() { Site target = new Site(1); // setup the site target.AddMessage(new Operation(Enumerations.OperationMode.Begin, 1)); target.AddMessage(new Operation(Enumerations.OperationMode.Read, 1, 2)); target.AddMessage(new Operation(Enumerations.OperationMode.Write, 1, 2, 40)); target.AddMessage(new Operation(Enumerations.OperationMode.Read, 2, 2)); target.AddMessage(new Operation(Enumerations.OperationMode.Write, 2, 4, 30)); target.AddMessage(new Operation(Enumerations.OperationMode.Read, 2, 4)); List<Result> actual = target.Tick(); List<Result> expected = new List<Result>(); expected.Add(new Result(1, Enumerations.OperationMode.Begin, 1, Enumerations.ResultStatus.Success, new List<int>() {1})); expected.Add(new Result(1, Enumerations.OperationMode.Read, 1, Enumerations.ResultStatus.Success, new List<int>() {1}, 20, 2)); expected.Add(new Result(1, Enumerations.OperationMode.Write, 1, Enumerations.ResultStatus.Success, new List<int>() {1}, dataItem: 2)); expected.Add(new Result(2, Enumerations.OperationMode.Read, 1, Enumerations.ResultStatus.Failure, new List<int>() {1}, 0, 2)); expected.Add(new Result(2, Enumerations.OperationMode.Write, 1, Enumerations.ResultStatus.Success, new List<int>() {2}, 0, 4)); expected.Add(new Result(2, Enumerations.OperationMode.Read, 1, Enumerations.ResultStatus.Success, new List<int>() {2}, 30, 4)); for (int i = 0; i < Math.Max(actual.Count, expected.Count); i++) { Assert.AreEqual(expected[i].DataItem, actual[i].DataItem); Assert.AreEqual(expected[i].Status, actual[i].Status); Assert.AreEqual(expected[i].TransId[0], actual[i].TransId[0]); Assert.AreEqual(expected[i].Val, actual[i].Val); Assert.AreEqual(1, actual[i].SiteNumber); Assert.AreEqual(expected[i].OpMode, actual[i].OpMode); } // Nothing should be returned because: // a. no new operations were enqueued and // b. no data items became free because of operations actual = target.Tick(); Assert.AreEqual(0, actual.Count); // make (1) release all locks and commit all values // thus (2) can read data item 1 and should read the value committed by (1) target.AddMessage(new Operation(Enumerations.OperationMode.Commit, 1)); target.AddMessage(new Operation(Enumerations.OperationMode.Read, 2, 2)); actual = target.Tick(); expected = new List<Result>(); expected.Add(new Result(1, Enumerations.OperationMode.Commit, 1, Enumerations.ResultStatus.Success, new List<int>() {1}, dataItem:-1)); expected.Add(new Result(1, Enumerations.OperationMode.Read, 1, Enumerations.ResultStatus.Success, new List<int>() {2}, 40, 2)); for (int i = 0; i < Math.Max(actual.Count, expected.Count); i++) { Assert.AreEqual(expected[i].DataItem, actual[i].DataItem); Assert.AreEqual(expected[i].Status, actual[i].Status); Assert.AreEqual(expected[i].TransId[0], actual[i].TransId[0]); Assert.AreEqual(expected[i].Val, actual[i].Val); Assert.AreEqual(1, actual[i].SiteNumber); Assert.AreEqual(expected[i].OpMode, actual[i].OpMode); } }
public void TestMVCC() { Site target = new Site(1); // Setup the site target.AddMessage(new Operation(Enumerations.OperationMode.Write, 1, 2, 5)); target.AddMessage(new Operation(Enumerations.OperationMode.Commit, 1, 2, ts:1)); target.AddMessage(new Operation(Enumerations.OperationMode.Read, 2, 2, ro: true, ts: 0)); List<Result> actual = target.Tick(); Result ROResult = actual.Find(matching => matching.IssuingTransaction == 2); // RO should have read the original value of data item 2 Assert.AreEqual(20, ROResult.Val); target.AddMessage(new Operation(Enumerations.OperationMode.Write, 3, 2, 50)); target.AddMessage(new Operation(Enumerations.OperationMode.Commit, 3, 2, ts: 2)); target.AddMessage(new Operation(Enumerations.OperationMode.Read, 4, 2, ro: true, ts: 2)); target.AddMessage(new Operation(Enumerations.OperationMode.Read, 5, 2, ro: true, ts: 0)); target.AddMessage(new Operation(Enumerations.OperationMode.Read, 6, 2, ro: true, ts: 3)); actual = target.Tick(); // transaction ID 4 has issued a read command with ts = 2, so it should read 5 (value committed at time 0, before ts=1) ROResult = actual.Find(matching => matching.IssuingTransaction == 4); Assert.AreEqual(5, ROResult.Val); // transaction ID 5 has issued a read command with ts = 0, so it should read 20 (original value) ROResult = actual.Find(matching => matching.IssuingTransaction == 5); Assert.AreEqual(20, ROResult.Val); // Transaction ID 6 has issued a read command with ts = 3, so it should read 50 ROResult = actual.Find(matching => matching.IssuingTransaction == 6); Assert.AreEqual(50, ROResult.Val); // a transction should read values written BEFORE its timestamp target.AddMessage(new Operation(Enumerations.OperationMode.Write, 7, 4, 4)); target.AddMessage(new Operation(Enumerations.OperationMode.Commit, 7, ts: 1)); target.AddMessage(new Operation(Enumerations.OperationMode.Read, 8, 4, ro: true, ts: 1)); actual = target.Tick(); ROResult = actual.Find(matching => matching.IssuingTransaction == 8); Assert.AreEqual(40, ROResult.Val); }
public void RecoverTest() { Site target = new Site(4); target.Fail(0); target.Recover(); Assert.AreEqual(Enumerations.SiteStatus.Active, target.Status); for (int i = 2; i <= 20; i += 2) { LockManagerTableEntry entry = target.GetCopyOfEntry(i); Assert.AreEqual(1, entry.ActiveLocks.Count); Assert.AreEqual(int.MinValue, entry.ActiveLocks[0].TransactionId); } }
public void ProcessOperationTest() { Site target = new Site(2); // begin op should always succeed Operation currentOp = new Operation(Enumerations.OperationMode.Begin, 1, 1); Result actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Success, actual.Status); Assert.AreEqual(currentOp.OpMode, actual.OpMode); // A write op here would succeed currentOp = new Operation(Enumerations.OperationMode.Write, 1, 2, 5); actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Success, actual.Status); Assert.AreEqual(currentOp.OpMode, actual.OpMode); Assert.AreEqual(2, actual.SiteNumber); // A read by the same transaction should succeed currentOp = new Operation(Enumerations.OperationMode.Read, 1, 2); actual = target.ProcessOperation(currentOp); // find out what value is read here Assert.AreEqual(Enumerations.ResultStatus.Success, actual.Status); Assert.AreEqual(5, actual.Val); Assert.AreEqual(2, actual.SiteNumber); Assert.AreEqual(currentOp.OpMode, actual.OpMode); // A read by a different transaction should fail currentOp = new Operation(Enumerations.OperationMode.Read, 2, 2); actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Failure, actual.Status); Assert.AreEqual(2, actual.SiteNumber); Assert.AreEqual(currentOp.OpMode, actual.OpMode); // A commit should succeed currentOp = new Operation(Enumerations.OperationMode.Commit, 1, ts: 1); actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Success, actual.Status); Assert.AreEqual(2, actual.SiteNumber); Assert.AreEqual(currentOp.OpMode, actual.OpMode); // A read now should succeed and return the committed value of transaction 1 currentOp = new Operation(Enumerations.OperationMode.Read, 2, 2); actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Success, actual.Status); Assert.AreEqual(5, actual.Val); Assert.AreEqual(2, actual.SiteNumber); Assert.AreEqual(currentOp.OpMode, actual.OpMode); // A read by another transaction should succeed (since no write locks) and return committed value of transaction 1 currentOp = new Operation(Enumerations.OperationMode.Read, 3, 2); actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Success, actual.Status); Assert.AreEqual(5, actual.Val); Assert.AreEqual(2, actual.SiteNumber); Assert.AreEqual(currentOp.OpMode, actual.OpMode); // A write by another transaction should fail currentOp = new Operation(Enumerations.OperationMode.Write, 4, 2, 5); actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Failure, actual.Status); Assert.AreEqual(2, actual.SiteNumber); Assert.AreEqual(currentOp.OpMode, actual.OpMode); // a commit should succeed currentOp = new Operation(Enumerations.OperationMode.Commit, 2); actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Success, actual.Status); Assert.AreEqual(2, actual.SiteNumber); // a commit should succeed currentOp = new Operation(Enumerations.OperationMode.Commit, 3); actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Success, actual.Status); Assert.AreEqual(2, actual.SiteNumber); Assert.AreEqual(currentOp.OpMode, actual.OpMode); // A write should succeed now currentOp = new Operation(Enumerations.OperationMode.Write, 4, 2, 2); actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Success, actual.Status); Assert.AreEqual(2, actual.SiteNumber); // Dont know what to do with abort yet currentOp = new Operation(Enumerations.OperationMode.Abort, 4); actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Success, actual.Status); Assert.AreEqual(2, actual.SiteNumber); Assert.AreEqual(currentOp.OpMode, actual.OpMode); // Handle some read only transactions and make sure they are correct // This should return the latest value since it has the largest timestamp currentOp = new Operation(Enumerations.OperationMode.Read, 4, 2, ro: true, ts: 5); actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Success, actual.Status); Assert.AreEqual(5, actual.Val); Assert.AreEqual(currentOp.OpMode, actual.OpMode); // This should return the original value since it has the smallest timestamp currentOp = new Operation(Enumerations.OperationMode.Read, 4, 2, ro: true, ts: 0); actual = target.ProcessOperation(currentOp); Assert.AreEqual(Enumerations.ResultStatus.Success, actual.Status); Assert.AreEqual(20, actual.Val); Assert.AreEqual(2, actual.SiteNumber); Assert.AreEqual(currentOp.OpMode, actual.OpMode); }
/// <summary> /// Date: 12/3/2011 /// A wrapper for site.AddMessage /// </summary> /// <param name = "site">The site.</param> /// <param name = "op">The op.</param> private void SendOpToSite(Site site, Operation op) { site.AddMessage(op); }