Example #1
0
 public GetVersionListRequest(
     string tableId,
     object recordKey,
     TxList <VersionEntry> localContainer,
     TxList <VersionEntry> remoteContainer = null)
     : base(tableId, recordKey, -1)
 {
     this.LocalContainer  = localContainer;
     this.RemoteContainer = remoteContainer;
 }
Example #2
0
 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;
        }
Example #4
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;
        }
        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);
        }
Example #6
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;
        }
Example #7
0
 public TxObjPoolList(int initialPoolSize = INIT_POOL_SIZE)
 {
     this.pool = new TxList <T>();
     this.pool.ResizeAndFill(initialPoolSize);
     this.size = 0;
 }