public IAsyncResult BeginAdd(Message msg, ulong id, AsyncCallback cb, object state) { try { this.rwLock.EnterWriteLock(); this.PurgeExpired(); var cmsg = new CachedMessage(msg.SignalKey, msg.Value, msg.Created, id); if (this.messageIndex.Count + 1 < CapacityLimit) { // add and complete this.AddToCache(cmsg); return new CompletedAsyncResult(cb, state); } else { // move the 'Add' operation to pending until we've got room to // add the item and complete once the item has been dequeued // calling Complete on the AR var addAsyncResult = new AddAsyncResult(cb, state); this.pendingAdds.EnqueueAndDispatch(cmsg, addAsyncResult.Complete); return addAsyncResult; } } finally { this.rwLock.ExitWriteLock(); } }
public bool TryGetNext(IEnumerable<string> eventKeys, ref ushort hwmp, out Message msg) { this.PurgeExpired(); msg = null; try { this.rwLock.EnterReadLock(); if (this.messageIndex.Count > 0) { var hwm = (this.messageIndex.Keys[this.messageIndex.Count - 1] / 0x10000) * 0x10000 + hwmp; // binary search to the right index int i = 0, l = 0, r = this.messageIndex.Count - 1; while (l <= r) { i = l + (r - l) / 2; var v = this.messageIndex.Values[i].Id; // check to see if value is equal to item in array if (hwm == v) { break; } if (hwm < v) { r = i - 1; } else { l = i + 1; } } if (i > l) { i = l; } // get the next message if there is one left for (; i < this.messageIndex.Count; i++) { if (this.messageIndex.Values[i].Id <= hwm ) { continue; } if (!eventKeys.Contains(this.messageIndex.Values[i].SignalKey)) { hwmp = (ushort)(this.messageIndex.Values[i].Id & 0xffff); continue; } var cmsg = this.messageIndex.Values[i]; msg = cmsg; hwmp = (ushort)(cmsg.Id & 0xffff); return true; } } } finally { this.rwLock.ExitReadLock(); } return false; }