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; } }
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; }
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(); }
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 }; }
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; }
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; }
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; }
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); } }
static private void UploadFail(UploadVersionRequest req) { req.RemoteVerEntry = req.VersionEntry; req.Result = false; req.Finished = true; }
internal virtual void Visit(UploadVersionRequest req) { }