मैंने वास्तव में वास्तविक स्रोत का अध्ययन करने के लिए समय निकाला, सरासर जिज्ञासा से बाहर, और इसके पीछे का विचार काफी सरल है। इस पोस्ट को लिखने के समय सबसे हाल का संस्करण 3.2.1 है।
पूर्व-आवंटित ईवेंट्स को सहेजने के लिए एक बफर है जो उपभोक्ताओं के डेटा को पढ़ने के लिए रखेगा।
बफर इसकी लंबाई के झंडे (पूर्णांक सरणी) के सरणी द्वारा समर्थित है जो बफर स्लॉट की उपलब्धता का वर्णन करता है (विवरण के लिए आगे देखें)। सरणी को एक जावा # AtomicIntegerArray की तरह एक्सेस किया जाता है, इसलिए इस अन्वेषण के उद्देश्य के लिए आप इसे एक मान सकते हैं।
किसी भी संख्या में निर्माता हो सकते हैं। जब निर्माता बफर को लिखना चाहता है, तो एक लंबी संख्या उत्पन्न होती है (जैसा कि एटॉमिकलॉन्ग # getAndIncrement को कॉल करने में, विघटनकर्ता वास्तव में अपने स्वयं के कार्यान्वयन का उपयोग करता है, लेकिन यह उसी तरीके से काम करता है)। आइए, इस जेनरेट किए गए प्रोड्यूसर को लंबे समय तक कॉल करें। एक समान तरीके से, एक ConsumerCallId उत्पन्न होता है जब एक उपभोक्ता ENDS बफर से एक स्लॉट को पढ़ता है। सबसे हाल ही में ConsumerCallId पहुँचा है।
(यदि कई उपभोक्ता हैं, तो सबसे कम आईडी वाला कॉल चुना जाता है।)
इन आईडी की तुलना तब की जाती है, और यदि दोनों के बीच अंतर कम है कि बफर पक्ष, निर्माता को लिखने की अनुमति है।
(यदि निर्माता हाल ही के उपभोक्ताकॉल आई + बफरसाइज से अधिक है, तो इसका मतलब है कि बफर भरा हुआ है, और निर्माता तब तक बस इंतजार करने के लिए मजबूर है जब तक कि कोई स्पॉट उपलब्ध नहीं हो जाता।)
तब निर्माता को उसके कॉल आईड के आधार पर बफर में स्लॉट दिया जाता है (जो कि prducerCallId modulo बफरसाइज़ है, लेकिन चूंकि बफरसाइज़ हमेशा 2 की शक्ति होती है (बफर निर्माण पर लागू सीमा), जिस एक्टल ऑपरेशन का उपयोग किया जाता है, वह है ))। यह तब उस स्लॉट में ईवेंट को संशोधित करने के लिए स्वतंत्र है।
(वास्तविक एल्गोरिथ्म थोड़ा और अधिक जटिल है, जिसमें अनुकूलन के उद्देश्यों के लिए एक अलग परमाणु संदर्भ में हाल के उपभोक्ता आईडी को शामिल करना शामिल है)
जब घटना को संशोधित किया गया था, तो परिवर्तन "प्रकाशित" है। ध्वज सरणी में संबंधित स्लॉट को प्रकाशित करते समय अद्यतन ध्वज से भरा जाता है। फ्लैग वैल्यू लूप की संख्या है (निर्माताकैलिड को बफरसेज द्वारा विभाजित किया गया है (फिर से बफरसिज़ 2 की शक्ति है, वास्तविक ऑपरेशन एक सही बदलाव है)।
इसी तरह से उपभोक्ताओं की संख्या हो सकती है। जब भी कोई उपभोक्ता बफर का उपयोग करना चाहता है, तो एक ConsumerCallId उत्पन्न होता है (यह निर्भर करता है कि उपभोक्ताओं को निष्क्रिय करने के लिए कैसे जोड़ा गया था, आईडी पीढ़ी में प्रयुक्त परमाणु को साझा किया जा सकता है या उनमें से प्रत्येक के लिए अलग हो सकता है)। यह ConsumerCallId तब सबसे हाल ही में किए गए ProductCallId की तुलना में है, और यदि यह दो से कम है, तो पाठक को प्रगति करने की अनुमति है।
(इसी तरह अगर निर्माताकॉल आईड भी उपभोक्ताकॉल आइडी के लिए है, तो इसका मतलब है कि बफर समान है और उपभोक्ता को इंतजार करने के लिए मजबूर किया जाता है। विघटनकारी निर्माण के दौरान प्रतीक्षा के तरीके को एक वैस्टस्ट्रेगी द्वारा परिभाषित किया जाता है।)
व्यक्तिगत उपभोक्ताओं (अपने स्वयं के आईडी जनरेटर के साथ) के लिए, अगली चीज की जाँच बैच उपभोग करने की क्षमता है। बफर में स्लॉट्स की जांच उपभोक्ता से संबंधित एक से की जाती है (हाल ही में निर्माता के लिए) के रूप में एक ही तरीके से सूचकांक निर्धारित किया जाता है, हाल ही में एक निर्माता से संबंधित है।
वे उपभोक्ता सरणी में उत्पन्न ध्वज मूल्य के खिलाफ ध्वज सरणी में लिखे गए ध्वज मूल्य की तुलना करके एक लूप में जांच की जाती है। यदि झंडे मेल खाते हैं तो इसका मतलब है कि स्लॉट्स को भरने वाले उत्पादकों ने अपने बदलाव शुरू कर दिए हैं। यदि नहीं, तो लूप टूट गया है, और उच्चतम प्रारंभ किया गया changeId वापस आ गया है। ChangeId में ConsumerCallId से प्राप्त किए गए स्लॉट को बैच में उपभोग किया जा सकता है।
यदि उपभोक्ताओं का एक समूह (साझा आईडी जनरेटर वाले) एक साथ पढ़ता है, तो हर एक केवल एक ही कॉलआईड लेता है, और केवल उस एकल कॉलआईड के लिए स्लॉट की जाँच की जाती है और वापस आ जाता है।