0

I'm implementation stock exachange engine. I receive ticker data via UDP, each udp multicast packet has Sequence Number. Exchange sends packets one by one but because UDP doesn't garantee order they may be (and will be) received in slighty "mixed" order, as an example:

1 2 3 5 4 6 7 10 9 8 11 12 13 14 15

Assuming that I receive packets in right order everything will be easy - I can just use Queue to add packets and dequeue them later. But because packets are not completely ordered I have several problems:

  • What structure to use to store packets? I need ability to queue and dequeue packets and I also need ability to add packets at arbitrary possition in array
  • I need to rise "recover" procedure if some packet is lost. So every time when "nextPacketSequenceNumber != currentPacketSequenceNumber + 1" I should wait for say 5 ms and probably packet will arrive, if not so I should recover. For example

    1 2 3 5 ... after 5 ms .... 4   - OK
    1 2 3 5 ... after 10 ms .... 4 - recover
    1 2 3 5 6 7  - recover
    
Oleg Vazhnev
  • 21,122
  • 47
  • 154
  • 286
  • 1
    `What structure to use to store packets?` Is that all what you are asking? Use `SortedDictionary` or `SortedList` – L.B Mar 07 '12 at 21:44

4 Answers4

0

You can use a priority queue to solve the reordering problem, with the sequence numbers as keys (priorities). The simplest priority queue is just an ordered dictionary. The recovering problem can be solved using a combination of a priority queue and an alarm clock.

Community
  • 1
  • 1
Fred Foo
  • 328,932
  • 68
  • 689
  • 800
  • I think that priority queue would be a good choice but general priority queue allows elements with the same priority. In my case each element has own priority and priorities goes one by one so I should probably write my own priority queue because I can make it faster than general priority queue. – Oleg Vazhnev Mar 09 '12 at 11:53
  • @javapowered: then a simple `SortedDictionary` should suffice. – Fred Foo Mar 09 '12 at 12:23
0

It might not be the most efficient way to do it, but I've used OrderedDictionary (though SortedDictionary is probably more appropriate) for handling the out of order issue in the past. Use the sequence number as the key and the packet data as the value.

Unfortunately, I can't speak to your second question (without a lot of effort). The only thing I'd suggest is to extend your protocol to allow a recall sort of message which could be sent by the receiver to the originator to tell them to resend the packet because the original was dropped. I have logic like this (only far more sophisticated), though it is company property so I can't share it. Hopefully, this will be enough to get you by.

M.Babcock
  • 18,075
  • 5
  • 50
  • 83
0

The problem gets more complicated if the ordering is critical - for example, you can use a priority queue but you also don't want to process anything off the queue unless its the next in the sequence. So you might want to implement a priority queue which also blocks based on sequence.

In that case you probably want to kick off the recovery process in a separate thread as soon as you find a missing packet - there's no point waiting - if the packet arrives then fine, you can ignore the recovery result.

This is similar to jitter buffering in audio streams to re-order UDP packets.http://en.wikipedia.org/wiki/Jitter#Jitter_buffers

vladimir e.
  • 713
  • 3
  • 7
0

Because sequence numbers are sequential integers, an array works very well for storage. But they also advance endlessly, so you want index reuse in circular fashion like a ring buffer.

Another way to look at this is as a ring buffer with random access (not just FIFO).

Ben Voigt
  • 260,885
  • 36
  • 380
  • 671