Ejemplo n.º 1
0
        internal override void Visit(UpdateVersionMaxCommitTsRequest req)
        {
            VersionEntry verEntry = req.RemoteVerEntry;

            if (verEntry == null)
            {
                ConcurrentDictionary <long, VersionEntry> versionList = null;
                if (!this.dict.TryGetValue(req.RecordKey, out versionList))
                {
                    throw new TransactionException("The specified record does not exist.");
                }

                if (!versionList.TryGetValue(req.VersionKey, out verEntry))
                {
                    throw new TransactionException("The specified version does not exist.");
                }
            }

            Debug.Assert(verEntry.VersionKey == req.VersionKey);

            //int ticket = verEntry.EnterQueuedLatch();
            verEntry.WriteLock();
            Interlocked.Exchange(
                ref verEntry.MaxCommitTs,
                Math.Max(req.MaxCommitTs, Interlocked.Read(ref verEntry.MaxCommitTs)));
            VersionEntry.CopyFromRemote(verEntry, req.LocalVerEntry);
            //verEntry.ExitQueuedLatch(ticket);
            verEntry.UnWriteLock();

            req.Result   = req.LocalVerEntry;
            req.Finished = true;
        }
Ejemplo n.º 2
0
        internal override void Visit(ReplaceVersionRequest req)
        {
            VersionEntry entry = req.RemoteVerEntry;

            if (entry == null)
            {
                ConcurrentDictionary <long, VersionEntry> versionList = null;
                if (!this.dict.TryGetValue(req.RecordKey, out versionList))
                {
                    throw new TransactionException("The specified record does not exist.");
                }

                if (!versionList.TryGetValue(req.VersionKey, out entry))
                {
                    throw new TransactionException("The specified version does not exist.");
                }
            }

            Debug.Assert(entry.VersionKey == req.VersionKey);
            // Debug Assertion
            // if (!entry.RecordKey.Equals(req.RecordKey))
            // {
            //     throw new Exception("Inconsistent record key");
            // }

            //int ticket = entry.EnterQueuedLatch();
            entry.WriteLock();
            if (Interlocked.Read(ref entry.TxId) == req.SenderId &&
                Interlocked.Read(ref entry.EndTimestamp) == req.ExpectedEndTs)
            {
                Interlocked.Exchange(ref entry.BeginTimestamp, req.BeginTs);
                Interlocked.Exchange(ref entry.EndTimestamp, req.EndTs);
                Interlocked.Exchange(ref entry.TxId, req.TxId);
                VersionEntry.CopyFromRemote(entry, req.LocalVerEntry);
                // req.LocalVerEntry.RecordKey = req.RecordKey;
            }
            //entry.ExitQueuedLatch(ticket);
            entry.UnWriteLock();

            req.Result   = req.LocalVerEntry;
            req.Finished = true;
        }
Ejemplo n.º 3
0
        internal override void Visit(ReadVersionRequest req)
        {
            VersionEntry versionEntry = req.RemoteVerEntry;

            if (versionEntry == null)
            {
                ConcurrentDictionary <long, VersionEntry> versionList = null;
                if (!this.dict.TryGetValue(req.RecordKey, out versionList))
                {
                    req.Result   = null;
                    req.Finished = true;
                    return;
                }

                if (!versionList.TryGetValue(req.VersionKey, out versionEntry))
                {
                    req.Result   = null;
                    req.Finished = true;
                    return;
                }
            }

            Debug.Assert(Interlocked.Read(ref versionEntry.VersionKey) == req.VersionKey);
            // Debug Assertion
            // if (!versionEntry.RecordKey.Equals(req.RecordKey))
            // {
            //     throw new Exception("Inconsistent record key");
            // }

            //int ticket = versionEntry.EnterQueuedLatch();
            versionEntry.ReadLock();
            VersionEntry.CopyFromRemote(versionEntry, req.LocalVerEntry);
            //versionEntry.ExitQueuedLatch(ticket);
            versionEntry.UnReadLock();

            req.Result   = req.LocalVerEntry;
            req.Finished = true;
        }
Ejemplo n.º 4
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;
        }