public GetVersionListRequest( string tableId, object recordKey, TxList <VersionEntry> localContainer, TxList <VersionEntry> remoteContainer = null) : base(tableId, recordKey, -1) { this.LocalContainer = localContainer; this.RemoteContainer = remoteContainer; }
public void Set( string tableId, object recordKey, long senderId, TxList <VersionEntry> localContainer, TxList <VersionEntry> remoteContainer = null) { this.TableId = tableId; this.RecordKey = recordKey; this.VersionKey = -1L; this.LocalContainer = localContainer; this.RemoteContainer = remoteContainer; this.SenderId = senderId; }
internal override void Visit(GetVersionListRequest req) { Dictionary <long, VersionEntry> versionList = null; if (!this.dict.TryGetValue(req.RecordKey, out versionList)) { req.RemoteVerList = null; req.Result = 0; req.Finished = true; return; } VersionEntry tailPointer = versionList[SingletonDictionaryVersionTable.TAIL_KEY]; long lastVersionKey = tailPointer.BeginTimestamp; TxList <VersionEntry> localList = req.LocalContainer; TxList <VersionEntry> remoteList = req.RemoteContainer; int entryCount = 0; // Only returns top 2 newest versions. This is enough for serializability. // For other isolation levels, more versions may need to be returned. // When old versions may be truncated, it is desirable to maintain a head pointer as well, // so as to increase the lower bound of version keys and reduce the number of iterations. while (lastVersionKey >= 0 && entryCount < 2) { // To make it run under .Net 4.5 VersionEntry verEntry = null; versionList.TryGetValue(lastVersionKey, out verEntry); if (verEntry != null) { VersionEntry.CopyValue(verEntry, localList[entryCount]); remoteList.Add(verEntry); entryCount++; if (verEntry.TxId == VersionEntry.EMPTY_TXID) { break; } } lastVersionKey--; } req.RemoteVerList = versionList; req.Result = entryCount; req.Finished = true; }
internal override void Visit(GetVersionListRequest req) { if (!this.dict.TryGetValue(req.RecordKey, out VersionList versionList)) { req.RemoteVerList = null; req.Result = 0; req.Finished = true; return; } TxList <VersionEntry> localList = req.LocalContainer; TxList <VersionEntry> remoteList = req.RemoteContainer; int entryCount = 0; versionList.TryPeek( out VersionEntry lastVersion, out VersionEntry secondToLastEntry); while (Interlocked.CompareExchange(ref lastVersion.latch, 1, 0) != 0) { ; } VersionEntry.CopyValue(lastVersion, localList[entryCount]); Interlocked.Exchange(ref lastVersion.latch, 0); // Add a reference to a version entry. No need to take the latch. remoteList.Add(lastVersion); entryCount++; if (lastVersion.TxId != VersionEntry.EMPTY_TXID) { while (Interlocked.CompareExchange(ref secondToLastEntry.latch, 1, 0) != 0) { ; } VersionEntry.CopyValue(secondToLastEntry, localList[entryCount]); Interlocked.Exchange(ref secondToLastEntry.latch, 0); // Add a reference to a version entry. No need to take the latch. remoteList.Add(secondToLastEntry); entryCount++; } req.RemoteVerList = versionList; req.Result = entryCount; req.Finished = true; }
private int ExtractVersionEntry( byte[][] response, TxList <VersionEntry> dest) { Debug.Assert(response.Length <= 4 || response.Length % 2 == 0); int entryCount = response.Length / 2; long[] debugKeys = new long[entryCount]; for (int i = 0; i < entryCount; ++i) { int versionKeyIndex = i * 2; long versionKey = BitConverter.ToInt64( response[versionKeyIndex], 0); byte[] entryBytes = response[versionKeyIndex + 1]; VersionEntry.Deserialize( versionKey, entryBytes, dest[i]); debugKeys[i] = versionKey; } if (debugKeys.Length == 2) { Debug.Assert(debugKeys[0] + 1 == debugKeys[1]); } return(entryCount); }
internal override void Visit(GetVersionListRequest req) { ConcurrentDictionary <long, VersionEntry> versionList = null; if (!this.dict.TryGetValue(req.RecordKey, out versionList)) { req.RemoteVerList = null; req.Result = 0; req.Finished = true; return; } int entryCount = 0; // The value at -1 in the version list is a special entry, // whose beginTimestamp points to the newest version. VersionEntry tailEntry = null; versionList.TryGetValue(SingletonDictionaryVersionTable.TAIL_KEY, out tailEntry); long lastVersionKey = Interlocked.Read(ref tailEntry.BeginTimestamp); TxList <VersionEntry> localList = req.LocalContainer; TxList <VersionEntry> remoteList = req.RemoteContainer; // Only returns top 2 newest versions. This is enough for serializability. // For other isolation levels, more versions may need to be returned. // When old versions may be truncated, it is desirable to maintain a head pointer as well, // so as to increase the lower bound of version keys and reduce the number of iterations. while (lastVersionKey >= 0 && entryCount < 2) { VersionEntry verEntry = null; if (versionList.TryGetValue(lastVersionKey, out verEntry)) { //int ticket = verEntry.EnterQueuedLatch(); verEntry.ReadLock(); // Debug Assertion // if (!verEntry.RecordKey.Equals(req.RecordKey)) // { // throw new Exception("Inconsistent record key"); // } VersionEntry.CopyFromRemote(verEntry, localList[entryCount]); //verEntry.ExitQueuedLatch(ticket); verEntry.UnReadLock(); // Here only add a reference to the list, no need to take the latch remoteList.Add(verEntry); entryCount++; if (Interlocked.Read(ref verEntry.TxId) == VersionEntry.EMPTY_TXID) { break; } } lastVersionKey--; } req.RemoteVerList = versionList; req.Result = entryCount; req.Finished = true; }
public TxObjPoolList(int initialPoolSize = INIT_POOL_SIZE) { this.pool = new TxList <T>(); this.pool.ResizeAndFill(initialPoolSize); this.size = 0; }