コード例 #1
0
        internal override void Visit(UploadVersionRequest req)
        {
            VersionList versionList = req.RemoteVerList as VersionList;

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

            if (versionList.TryAdd(req.VersionEntry, out VersionEntry remoteEntry))
            {
                req.RemoteVerEntry = remoteEntry;
                req.Result         = true;
                req.Finished       = true;
                return;
            }
            else
            {
                // The same version key has been added before or by a concurrent tx.
                // The new version cannot be inserted.
                req.RemoteVerEntry = req.VersionEntry;
                req.Result         = false;
                req.Finished       = true;
            }
        }
コード例 #2
0
        internal override void Visit(UploadVersionRequest req)
        {
            VersionEntry ve = this.GetVersionEntryByKey(req.TableId, req.RecordKey, req.VersionKey, req.LocalVerEntry);

            if (ve == null)
            {
                this.CQLExecute(string.Format(PartitionedCassandraVersionTable.CQL_UPLOAD_VERSION_ENTRY,
                                              req.TableId,
                                              req.RecordKey.ToString(),
                                              req.VersionEntry.VersionKey,
                                              req.VersionEntry.BeginTimestamp,
                                              req.VersionEntry.EndTimestamp,
                                              BytesSerializer.ToHexString(BytesSerializer.Serialize(req.VersionEntry.Record)),
                                              req.VersionEntry.TxId,
                                              req.VersionEntry.MaxCommitTs));
                req.RemoteVerEntry = req.VersionEntry;
                req.Result         = true;
            }
            else        // write-write conflict
            {
                req.RemoteVerEntry = req.VersionEntry;
                req.Result         = false;
            }

            req.Finished = true;
        }
コード例 #3
0
        internal override void Visit(UploadVersionRequest req)
        {
            // what is this line doing ???
            req.RemoteVerEntry = req.VersionEntry;

            byte[][] returnBytes = req.Result as byte[][];
            req.Result = returnBytes.IsSuccess();
        }
コード例 #4
0
        internal override void Visit(UploadVersionRequest req)
        {
            this.HashId = req.RecordKey as string;
            byte[] keyBytes   = BitConverter.GetBytes(req.VersionKey);
            byte[] valueBytes = VersionEntry.Serialize(req.VersionEntry);

            this.RedisReq = new RedisRequest(this.HashId, keyBytes, valueBytes, RedisRequestType.HSetNX)
            {
                ParentRequest = req
            };
        }
コード例 #5
0
        internal override void Visit(UploadVersionRequest req)
        {
            bool applied = this.CQLExecuteWithIfApplied(string.Format(CassandraVersionTable.CQL_UPLOAD_VERSION_ENTRY,
                                                                      req.TableId,
                                                                      req.RecordKey.ToString(),
                                                                      req.VersionEntry.VersionKey,
                                                                      req.VersionEntry.BeginTimestamp,
                                                                      req.VersionEntry.EndTimestamp,
                                                                      BytesSerializer.ToHexString(BytesSerializer.Serialize(req.VersionEntry.Record)),
                                                                      req.VersionEntry.TxId,
                                                                      req.VersionEntry.MaxCommitTs));

            req.Result   = applied ? 1L : 0L;
            req.Finished = true;
        }
コード例 #6
0
        internal override void Visit(UploadVersionRequest req)
        {
            string hashKey = GetHashKey(req);

            byte[][] args =
            {
                Encoding.ASCII.GetBytes(hashKey),
                BitConverter.GetBytes(req.VersionKey),
                VersionEntry.Serialize(req.VersionEntry)
            };

            var redisRequest = CreateLuaRequest(
                LuaScriptName.UPLOAD_NEW_VERSION, args);

            redisRequest.ParentRequest = req;
        }
コード例 #7
0
        internal override void Visit(UploadVersionRequest req)
        {
            Dictionary <long, VersionEntry> versionList = req.RemoteVerList as
                                                          Dictionary <long, VersionEntry>;

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

            if (versionList.ContainsKey(req.VersionKey))
            {
                req.RemoteVerEntry = req.VersionEntry;
                req.Result         = false;
            }
            else
            {
                versionList.Add(req.VersionKey, req.VersionEntry);

                // Take the dirty version entry to store the current largest version key
                VersionEntry tailEntry = versionList[SingletonDictionaryVersionTable.TAIL_KEY];
                tailEntry.BeginTimestamp = req.VersionKey;

                VersionEntry oldVersion = null;
                if (versionList.Count > VersionTable.VERSION_CAPACITY)
                {
                    long headKey = tailEntry.EndTimestamp;
                    tailEntry.EndTimestamp = headKey + 1;

                    versionList.TryGetValue(headKey, out oldVersion);
                    versionList.Remove(headKey);
                }

                req.RemoteVerEntry = oldVersion == null ? new VersionEntry() : oldVersion;
                req.Result         = true;
            }
            req.Finished = true;
        }
コード例 #8
0
        internal override void Visit(UploadVersionRequest req)
        {
            ConcurrentDictionary <long, VersionEntry> versionList = req.RemoteVerList as
                                                                    ConcurrentDictionary <long, VersionEntry>;

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

            if (versionList.TryAdd(req.VersionKey, req.VersionEntry))
            {
                req.VersionEntry.ResetLatchQueue();

                // The new version has been inserted successfully. Re-directs the tail pointer to the new version.
                VersionEntry tailEntry = null;
                versionList.TryGetValue(SingletonDictionaryVersionTable.TAIL_KEY, out tailEntry);

                long headKey = Interlocked.Read(ref tailEntry.EndTimestamp);
                long tailKey = Interlocked.Read(ref tailEntry.BeginTimestamp);

                if (req.VersionKey < headKey)
                {
                    versionList.Remove(req.VersionKey);
                    UploadFail(req);
                    return;
                }
                // Here we use Interlocked to atomically update the tail entry, instead of ConcurrentDict.TryUpdate().
                // This is because once created, the whole tail entry always stays and is never replaced.
                // All concurrent tx's only access the tail pointer, i.e., the beginTimestamp field.
                long oldVersion = Interlocked.Exchange(ref tailEntry.BeginTimestamp, req.VersionKey);

                // Debug Assertion
                // if (oldVersion != req.VersionKey - 1)
                // {
                //     throw new Exception("inconsistent version key");
                // }

                VersionEntry oldVerEntry = null;

                // EndTimestamp (headKey) being never set means we just insert
                // the first valid version. So the headKey should be redirected.
                if (headKey == VersionEntry.DEFAULT_END_TIMESTAMP)
                {
                    Interlocked.Exchange(ref tailEntry.EndTimestamp, tailKey);
                }
                else if (versionList.Count > VersionTable.VERSION_CAPACITY)
                {
                    Interlocked.Exchange(ref tailEntry.EndTimestamp, headKey + 1);
                    versionList.TryRemove(headKey, out oldVerEntry);
                    if (oldVerEntry != null)
                    {
                        this.recordPool.TryCache(oldVerEntry.Record);
                        oldVerEntry.Record = null;
                    }
                }

                // Debug Assertion
                // long debugTailkey = Interlocked.Read(ref tailEntry.BeginTimestamp);
                // if (debugTailkey != req.VersionKey)
                // {
                //     throw new Exception("Someone kicks in :(");
                // }

                req.RemoteVerEntry = oldVerEntry == null ? new VersionEntry() : oldVerEntry;
                req.Result         = true;
                req.Finished       = true;
                return;
            }
            else
            {
                // The same version key has been added before or by a concurrent tx.
                // The new version cannot be inserted.
                UploadFail(req);
            }
        }
コード例 #9
0
 static private void UploadFail(UploadVersionRequest req)
 {
     req.RemoteVerEntry = req.VersionEntry;
     req.Result         = false;
     req.Finished       = true;
 }
コード例 #10
0
 internal virtual void Visit(UploadVersionRequest req)
 {
 }