internal override void Visit(InsertTxIdRequest req) { string hashId = req.TxId.ToString(); if (this.redisVersionDbMode == RedisVersionDbMode.Cluster) { hashId = RedisVersionDb.PACK_KEY(RedisVersionDb.TX_KEY_PREFIX, hashId); } byte[][] keysBytes = { Encoding.ASCII.GetBytes(TxTableEntry.STATUS_STRING), Encoding.ASCII.GetBytes(TxTableEntry.COMMIT_TIME_STRING), Encoding.ASCII.GetBytes(TxTableEntry.COMMIT_LOWER_BOUND_STRING) }; byte[][] valuesBytes = { BitConverter.GetBytes((int)TxStatus.Ongoing), BitConverter.GetBytes(TxTableEntry.DEFAULT_COMMIT_TIME), BitConverter.GetBytes(TxTableEntry.DEFAULT_LOWER_BOUND) }; RedisRequest redisReq = this.NextRedisRequest(); redisReq.Set(hashId, keysBytes, valuesBytes, RedisRequestType.HMSet); redisReq.ParentRequest = req; }
internal override void Visit(ReplaceVersionRequest req) { string sha1 = this.redisLuaManager.GetLuaScriptSha1(LuaScriptName.REPLACE_VERSION_ENTRY); string hashId = req.RecordKey.ToString(); if (this.redisVersionDbMode == RedisVersionDbMode.Cluster) { hashId = RedisVersionDb.PACK_KEY(RedisVersionDb.VER_KEY_PREFIX, hashId); } byte[][] keysAndArgs = { Encoding.ASCII.GetBytes(hashId), BitConverter.GetBytes(req.VersionKey), BitConverter.GetBytes(req.BeginTs), BitConverter.GetBytes(req.EndTs), BitConverter.GetBytes(req.TxId), BitConverter.GetBytes(req.SenderId), BitConverter.GetBytes(req.ExpectedEndTs), RedisVersionDb.NEGATIVE_ONE_BYTES, }; RedisRequest redisReq = this.NextRedisRequest(); redisReq.Set(keysAndArgs, sha1, 1, RedisRequestType.EvalSha); redisReq.ParentRequest = req; }
internal byte[][] ProcessValueRequestInBatch(IEnumerable <RedisRequest> reqBatch) { RedisRequest lastRequest = null; int count = 0; foreach (RedisRequest req in reqBatch) { count++; lastRequest = req; this.EnqueueRedisRequest(req); } // Since requests may be executed in different batch, we must enusre all // requests are finished by checking whether the last request is finished lock (lastRequest) { while (!lastRequest.Finished) { System.Threading.Monitor.Wait(lastRequest); } } byte[][] values = new byte[count][]; count = 0; foreach (RedisRequest req in reqBatch) { values[count++] = (byte[])req.Result; } return(values); }
internal void EnqueueVersionEntryRequest(VersionEntryRequest req) { this.versionEntryVisitor.Invoke(req); RedisRequest redisReq = this.versionEntryVisitor.RedisReq; redisReq.ResponseVisitor = this.redisResponseVisitor; this.redisRequestQueue.Enqueue(redisReq); }
private RedisRequest CreateLuaRequest( LuaScriptName script, byte[][] args) { string sha1 = redisLuaManager.GetLuaScriptSha1(script); RedisRequest result = NextRedisRequest(); result.Set(args, sha1, 1, RedisRequestType.EvalSha); return(result); }
internal void ProcessVoidRequest(RedisRequest redisRequest) { this.EnqueueRedisRequest(redisRequest); lock (redisRequest) { while (!redisRequest.Finished) { System.Threading.Monitor.Wait(redisRequest); } } }
internal byte[] ProcessValueRequest(RedisRequest redisRequest) { this.EnqueueRedisRequest(redisRequest); lock (redisRequest) { while (!redisRequest.Finished) { System.Threading.Monitor.Wait(redisRequest); } } return((byte[])redisRequest.Result); }
internal long ProcessLongRequest(RedisRequest redisRequest) { this.EnqueueRedisRequest(redisRequest); lock (redisRequest) { while (!redisRequest.Finished) { System.Threading.Monitor.Wait(redisRequest); } } return((long)redisRequest.Result); }
private RedisRequest NextRedisRequest() { RedisRequest nextReq = null; while (reqIndex >= this.redisRequests.Count) { nextReq = new RedisRequest(this.RedisResponseVisitor); this.redisRequests.Add(nextReq); } nextReq = this.redisRequests[reqIndex]; this.reqIndex++; return(nextReq); }
internal void VisitRedisRequestQueue() { long now = DateTime.Now.Ticks / 10; if (now - lastFlushTime >= this.WindowMicroSec || this.redisRequestQueue.Count >= this.RequestBatchSize) { if (this.redisRequestQueue.Count > 0) { // ONLY FOR BENCHMARK TEST Interlocked.Increment(ref RedisConnectionPool.FLUSH_TIMES); if (this.redisRequestQueue.Count >= this.RequestBatchSize) { Interlocked.Increment(ref RedisConnectionPool.FLUSH_TIMES_UPTO_BATCH); } bool lockTaken = false; RedisRequest[] flushReqs = null; try { this.spinLock.Enter(ref lockTaken); // Copy a batch of elements to an array and clear the request queue, then release the lock. // It reduces the time holding the lock and let requests enqueue timely int flushCount = Math.Min(this.RequestBatchSize, this.redisRequestQueue.Count); if (flushCount > 0) { flushReqs = new RedisRequest[flushCount]; for (int i = 0; i < flushCount; i++) { flushReqs[i] = this.redisRequestQueue.Dequeue(); } } } finally { if (lockTaken) { this.spinLock.Exit(); } if (flushReqs != null) { this.Flush(flushReqs); } } } lastFlushTime = DateTime.Now.Ticks / 10; } }
internal override void Visit(ReadVersionRequest req) { string hashId = req.RecordKey.ToString(); if (this.redisVersionDbMode == RedisVersionDbMode.Cluster) { hashId = RedisVersionDb.PACK_KEY(RedisVersionDb.VER_KEY_PREFIX, hashId); } byte[] keyBytes = BitConverter.GetBytes(req.VersionKey); RedisRequest redisReq = this.NextRedisRequest(); redisReq.Set(hashId, keyBytes, RedisRequestType.HGet); redisReq.ParentRequest = req; }
internal override void Visit(UpdateTxStatusRequest req) { string hashId = req.TxId.ToString(); if (this.redisVersionDbMode == RedisVersionDbMode.Cluster) { hashId = RedisVersionDb.PACK_KEY(RedisVersionDb.TX_KEY_PREFIX, hashId); } byte[] keyBytes = Encoding.ASCII.GetBytes(TxTableEntry.STATUS_STRING); byte[] valueBytes = BitConverter.GetBytes((int)req.TxStatus); RedisRequest redisReq = this.NextRedisRequest(); redisReq.Set(hashId, keyBytes, valueBytes, RedisRequestType.HSet); redisReq.ParentRequest = req; }
/// <summary> /// Enqueues an incoming Redis request to a queue. Queued requests are periodically sent to Redis. /// </summary> /// <param name="request">The incoming request</param> /// <returns>The index of the spot the request takes</returns> private void EnqueueRedisRequest(RedisRequest request) { bool lockTaken = false; try { this.spinLock.Enter(ref lockTaken); this.redisRequestQueue.Enqueue(request); } finally { if (lockTaken) { this.spinLock.Exit(); } } }
internal override void Visit(GetTxEntryRequest req) { string hashId = req.TxId.ToString(); if (this.redisVersionDbMode == RedisVersionDbMode.Cluster) { hashId = RedisVersionDb.PACK_KEY(RedisVersionDb.TX_KEY_PREFIX, hashId); } byte[][] keyBytes = { Encoding.ASCII.GetBytes(TxTableEntry.STATUS_STRING), Encoding.ASCII.GetBytes(TxTableEntry.COMMIT_TIME_STRING), Encoding.ASCII.GetBytes(TxTableEntry.COMMIT_LOWER_BOUND_STRING) }; RedisRequest redisReq = this.NextRedisRequest(); redisReq.Set(hashId, keyBytes, RedisRequestType.HMGet); redisReq.ParentRequest = req; }
internal override void Visit(UpdateVersionMaxCommitTsRequest req) { string sha1 = this.redisLuaManager.GetLuaScriptSha1(LuaScriptName.UPDATE_VERSION_MAX_COMMIT_TS); string hashId = req.RecordKey.ToString(); if (this.redisVersionDbMode == RedisVersionDbMode.Cluster) { hashId = RedisVersionDb.PACK_KEY(RedisVersionDb.VER_KEY_PREFIX, hashId); } byte[][] keysAndArgs = { Encoding.ASCII.GetBytes(hashId), BitConverter.GetBytes(req.VersionKey), BitConverter.GetBytes(req.MaxCommitTs), RedisVersionDb.NEGATIVE_ONE_BYTES, }; RedisRequest redisReq = this.NextRedisRequest(); redisReq.Set(keysAndArgs, sha1, 1, RedisRequestType.EvalSha); redisReq.ParentRequest = req; }
internal override void Visit(SetCommitTsRequest req) { string hashId = req.TxId.ToString(); if (this.redisVersionDbMode == RedisVersionDbMode.Cluster) { hashId = RedisVersionDb.PACK_KEY(RedisVersionDb.TX_KEY_PREFIX, hashId); } string sha1 = this.redisLuaScriptManager.GetLuaScriptSha1(LuaScriptName.SET_AND_GET_COMMIT_TIME); byte[][] keys = { Encoding.ASCII.GetBytes(hashId), BitConverter.GetBytes(req.ProposedCommitTs), RedisVersionDb.NEGATIVE_ONE_BYTES, }; RedisRequest redisReq = this.NextRedisRequest(); redisReq.Set(keys, sha1, 1, RedisRequestType.EvalSha); redisReq.ParentRequest = req; }
internal override void Visit(UpdateCommitLowerBoundRequest req) { string hashId = req.TxId.ToString(); if (this.redisVersionDbMode == RedisVersionDbMode.Cluster) { hashId = RedisVersionDb.PACK_KEY(RedisVersionDb.TX_KEY_PREFIX, hashId); } string sha1 = this.redisLuaScriptManager.GetLuaScriptSha1(LuaScriptName.UPDATE_COMMIT_LOWER_BOUND); byte[][] keys = { Encoding.ASCII.GetBytes(hashId), BitConverter.GetBytes(req.CommitTsLowerBound), RedisVersionDb.NEGATIVE_ONE_BYTES, RedisVersionDb.NEGATIVE_TWO_BYTES, }; RedisRequest redisReq = this.NextRedisRequest(); redisReq.Set(keys, sha1, 1, RedisRequestType.EvalSha); redisReq.ParentRequest = req; }