Aslında gerçek kaynağı, meraktan çıkarmak için zaman ayırdım ve arkasındaki fikir oldukça basit. Bu yazıyı yazarken en son sürüm 3.2.1'dir.
Tüketicilerin okuması için verileri tutacak önceden tahsis edilmiş olayları saklayan bir arabellek vardır.
Arabellek, arabellek yuvalarının kullanılabilirliğini açıklayan bir dizi bayrakla (tamsayı dizisi) desteklenir (ayrıntılar için daha fazla bilgi). Diziye bir java # AtomicIntegerArray gibi erişilir, bu nedenle bu açıklama için bir tane olduğunu varsayabilirsiniz.
Herhangi bir sayıda üretici olabilir. Üretici arabelleğe yazmak istediğinde, uzun bir sayı üretilir (AtomicLong # getAndIncrement çağırırken olduğu gibi, Disruptor aslında kendi uygulamasını kullanır, ancak aynı şekilde çalışır). Buna uzun bir üreticiCallId adı verelim. Benzer bir şekilde, bir tüketici bir tampondan bir yuva okurken ENDS oluşturulur. En son ConsumerCallId öğesine erişilir.
(Çok sayıda tüketici varsa, en düşük kimliğe sahip çağrı seçilir.)
Bu kimlikler daha sonra karşılaştırılır ve ikisi arasındaki fark tampon tarafına göre daha azsa, üreticinin yazmasına izin verilir.
(ProducerCallId, yeni customerCallId + bufferSize değerinden büyükse, bu arabellek dolu demektir ve üretici bir nokta bulunana kadar veri yolunu beklemeye zorlanır.)
Üreticiye daha sonra callId (prducerCallId modulo bufferSize olan) arabellekte yuva atanır, ancak bufferSize her zaman 2 (tampon oluşturmada uygulanan sınır) gücü olduğundan, kullanılan etkin işlem manufacturerCallId & (bufferSize - 1'dir) )). Daha sonra o yuvadaki etkinliği değiştirmek ücretsizdir.
(Gerçek algoritma, optimizasyon amacıyla son tüketici kimliği ayrı bir atomik referansta önbelleğe almayı içeren biraz daha karmaşıktır.)
Etkinlik değiştirildiğinde, değişiklik "yayınlanır". Bayrak dizisindeki ilgili yuva yayınlanırken güncel bayrakla doldurulur. Bayrak değeri döngü sayısıdır (producerCallId, bufferSize değerine bölünür (yine bufferSize 2'nin gücü olduğundan, gerçek işlem sağdaki bir kaydırmadır).
Benzer bir şekilde, herhangi bir sayıda tüketici olabilir. Bir tüketici arabelleğe her erişmek istediğinde, bir customerCallId üretilir (tüketicilerin, kimlik oluşturmada kullanılan atomik her biri için paylaşılabilir veya ayrı olabilir. Bu ConsumCallId daha sonra en son producCCallId ile karşılaştırılır ve eğer ikisinden daha azsa, okuyucunun ilerlemesine izin verilir.
(Benzer şekilde manufacturerCallId, customerCallId için bile olsa, arabellek boştur ve tüketicinin beklemeye zorlandığı anlamına gelir. Bekleme şekli, yıkıcı oluşturma sırasında WaitStrategy tarafından tanımlanır.)
Bireysel tüketiciler için (kendi kimlik üreteçlerine sahip olanlar), kontrol edilen bir sonraki şey, toplu tüketim yeteneğidir. Tampondaki yuvalar, customerCallId ile ilgili olandan (endeks, üreticiler için olanla aynı şekilde belirlenir), en son manufacturerCallId ile ilgili olana göre incelenir.
Bayrak dizisinde yazılan bayrak değeri, customerCallId için oluşturulan bir bayrak değeri ile karşılaştırılarak bir döngüde incelenir. Bayraklar eşleşirse, yuvaları dolduran üreticiler değişikliklerini taahhüt etmiş demektir. Değilse, döngü bozulur ve taahhüt edilen en yüksek changeId döndürülür. ConsumerCallId ile changeId içinde alınan yuvalar toplu olarak tüketilebilir.
Bir grup tüketici birlikte okursa (paylaşılan kimlik oluşturucusuna sahip olanlar), her biri yalnızca tek bir callId alır ve yalnızca o tek callId için yuva kontrol edilir ve döndürülür.