/// <summary> /// TBD /// </summary> /// <param name="nonAcked">TBD</param> /// <param name="nacked">TBD</param> /// <param name="maxSeq">TBD</param> /// <returns>TBD</returns> public AckedSendBuffer <T> Copy(List <T> nonAcked = null, List <T> nacked = null, SeqNo maxSeq = null) { return(new AckedSendBuffer <T>(Capacity, maxSeq ?? MaxSeq) { Nacked = nacked ?? Nacked.ToArray().ToList(), NonAcked = nonAcked ?? NonAcked.ToArray().ToList() }); }
/// <summary> /// Processes an incoming acknowledgement and returns a new buffer with only unacknowledged elements remaining. /// </summary> /// <param name="ack">The received acknowledgement</param> /// <exception cref="ResendUnfulfillableException">Thrown if we couldn't fit all of the nacks stored inside <see cref="Ack"/> onto the buffer.</exception> /// <returns>An updated buffer containing the remaining unacknowledged messages</returns> public AckedSendBuffer <T> Acknowledge(Ack ack) { var newNacked = new List <T>(Nacked.Concat(NonAcked)).Where(x => ack.Nacks.Contains(x.Seq)).ToList(); if (newNacked.Count < ack.Nacks.Count) { throw new ResendUnfulfillableException(); } else { return(Copy(nonAcked: NonAcked.Where(x => x.Seq > ack.CumulativeAck).ToList(), nacked: newNacked)); } }
/// <summary> /// Puts a new message in the buffer. /// </summary> /// <param name="msg">The message to be stored for possible future transmission.</param> /// <exception cref="ArgumentException">Thrown if an out-of-sequence message is attempted to be stored.</exception> /// <exception cref="ResendBufferCapacityReachedException">Thrown if the resend buffer is beyond its capacity.</exception> /// <returns>The updated buffer.</returns> public AckedSendBuffer <T> Buffer(T msg) { if (msg.Seq <= MaxSeq) { throw new ArgumentException($"Sequence number must be monotonic. Received {msg.Seq} which is smaller than {MaxSeq}", nameof(msg)); } if (NonAcked.Count == Capacity) { throw new ResendBufferCapacityReachedException(Capacity); } return(Copy(nonAcked: NonAcked.Add(msg), maxSeq: msg.Seq)); }
/// <summary> /// Processes an incoming acknowledgement and returns a new buffer with only unacknowledged elements remaining. /// </summary> /// <param name="ack">The received acknowledgement</param> /// <exception cref="ResendUnfulfillableException">Thrown if we couldn't fit all of the nacks stored inside <see cref="Ack"/> onto the buffer.</exception> /// <returns>An updated buffer containing the remaining unacknowledged messages</returns> public AckedSendBuffer <T> Acknowledge(Ack ack) { if (ack.CumulativeAck > MaxSeq) { throw new ArgumentException(nameof(ack), $"Highest SEQ so far was {MaxSeq} but cumulative ACK is {ack.CumulativeAck}"); } var newNacked = ack.Nacks.Count == 0 ? ImmutableList <T> .Empty : Nacked.AddRange(NonAcked).Where(x => ack.Nacks.Contains(x.Seq)).ToImmutableList(); if (newNacked.Count < ack.Nacks.Count) { throw new ResendUnfulfillableException(); } else { return(Copy(nonAcked: NonAcked.Where(x => x.Seq > ack.CumulativeAck).ToImmutableList(), nacked: newNacked)); } }
/// <summary> /// Returns a <see cref="System.String" /> that represents this instance. /// </summary> /// <returns> /// A <see cref="System.String" /> that represents this instance. /// </returns> public override string ToString() { var nonAcked = string.Join(",", NonAcked.Select(x => x.ToString())); return($"[{nonAcked}]"); }
public override string ToString() { return(string.Format("[{0}]", string.Join(",", NonAcked.Select(x => x.ToString())))); }