Example #1
0
        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;
        }
        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;
        }
Example #3
0
        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;
        }