internal void Clear(long seqNum) { // TODO: fix this function. long uptoSeqnum = seqNum; lock (_lock) { while (uptoSeqnum > 0) { PublishContext ctx = null; Remove(uptoSeqnum, out ctx); uptoSeqnum--; } return; } }
internal bool Remove(long seqNum, out PublishContext returnValue) { SkipListNode current = _head; bool found = false; returnValue = null; lock (_lock) { for (int i = _levels - 1; i >= 0; i--) { for (; current.Neighbors[i] != null; current = current.Neighbors[i]) { if (current.Neighbors[i].seqNum == seqNum) { PublishContext ctx = current.Neighbors[i].ctx; current.Neighbors[i] = current.Neighbors[i].Neighbors[i]; returnValue = ctx; found = true; count--; break; } if (current.Neighbors[i].seqNum > seqNum) { if (!found) { found = false; returnValue = null; break; } } } } } if (!found) { returnValue = null; } return(found); }
public void SendReply(IMessage reply, IMessage request, ICompletionListener listener) { if (!IsConnected()) { throw new Exception("not connected"); } if (((JSONMessage)request).ReplyTo == null) { throw new ArgumentException("not a request message"); } JsonObject envelope = new JsonObject(); // synchronized to ensure message sequence numbers are ordered lock (writeLock) { long seqNum = Interlocked.Increment(ref messageIdGenerator); envelope.Add(ProtocolConstants.OP_FIELD, ProtocolOpConstants.OP_REPLY); envelope.Add(ProtocolConstants.SEQ_NUM_FIELD, seqNum); envelope.Add(ProtocolConstants.TO_FIELD, ((JSONMessage)request).ReplyTo); envelope.Add(ProtocolConstants.REQ_ID_FIELD, ((JSONMessage)request).ReqId); envelope.Add(ProtocolConstants.BODY_FIELD, ((JSONMessage)reply)._rawData()); PublishContext ctx = new PublishContext(seqNum, envelope.ToString(), reply, listener); if (protocol < 1) { throw new NotSupportedException("send reply is not supported with this server"); } if (maxMessageSize > 0 && ctx.GetJson().Length > maxMessageSize) { throw new Exception("maximum message size exceeded"); } requests.Put(seqNum, ctx); Queue(ctx); } }
internal void Put(long seqNum, PublishContext ctx) { lock (_lock) { int level = 0; int random = _rand.Next(); for (int R = random; (R & 1) == 1; R >>= 1) { level++; if (level == _levels) { _levels++; break; } } // Insert this node into the skip list SkipListNode newNode = new SkipListNode(seqNum, ctx, level + 1); count++; SkipListNode current = _head; for (int i = _levels - 1; i >= 0; i--) { for (; current.Neighbors[i] != null; current = current.Neighbors[i]) { if (current.Neighbors[i].seqNum > seqNum) { break; } } if (i <= level) { newNode.Neighbors[i] = current.Neighbors[i]; current.Neighbors[i] = newNode; } } } }
private void Queue(PublishContext ctx) { bool notifyWriterThread = false; try { lock (writeQueueLock) { if (writeQueue.Count == 0) { notifyWriterThread = true; } writeQueue.Enqueue(ctx); if (notifyWriterThread) { Monitor.Pulse(writeQueueLock); } } } catch (System.Threading.ThreadAbortException) { } catch (Exception) { } }