Basel का समानांतर इवैलुएशन और बढ़ोतरी वाला मॉडल.
डेटा मॉडल
डेटा मॉडल में ये आइटम शामिल होते हैं:
SkyValue
. इन्हें नोड भी कहा जाता है.SkyValues
ऐसे ऑब्जेक्ट हैं जिन्हें बदला नहीं जा सकता इसमें वह सभी डेटा शामिल है जो इस प्रोसेस के दौरान बना था और बिल्ड. उदाहरण के लिए: इनपुट फ़ाइलें, आउटपुट फ़ाइलें, टारगेट, और कॉन्फ़िगर की गई फ़ाइलें टारगेट के लिए.SkyKey
.SkyValue
का रेफ़रंस देने के लिए, ऐसा छोटा नाम जिसे बदला नहीं जा सकता. उदाहरण के लिए,FILECONTENTS:/tmp/foo
याPACKAGE://foo
.SkyFunction
. नोड, उनकी कुंजियों और डिपेंडेंट नोड के आधार पर बनता है.- नोड ग्राफ़. ऐसा डेटा स्ट्रक्चर जिसमें डिपेंडेंसी के बीच संबंध होता है नोड.
Skyframe
. इंक्रीमेंटल इवैलुएशन फ़्रेमवर्क Basel के लिए कोड नेम यह है आधारित है.
आकलन
बिल्ड पूरा करने के लिए, उस नोड का आकलन किया जाता है जो बिल्ड अनुरोध दिखाता है.
पहली बात, बेज़ल टॉप-लेवल की कुंजी के हिसाब से SkyFunction
ढूंढता है
SkyKey
. इसके बाद, फ़ंक्शन उन नोड के आकलन का अनुरोध करता है जिनकी उसे ज़रूरत होती है
टॉप-लेवल नोड का आकलन करें, जिससे हमें अन्य SkyFunction
कॉल मिलती हैं,
लीफ़ नोड तक पहुंचने तक. आम तौर पर, लीफ़ नोड वे होती हैं जिनसे पता चलता है कि
इनपुट फ़ाइलें शामिल हैं. अंत में, Basel को आखिर में
टॉप लेवल SkyValue
, कुछ खराब असर (जैसे कि फ़ाइल में मौजूद आउटपुट फ़ाइलें)
सिस्टम) और नोड के बीच की डिपेंडेंसी का डायरेक्टेड असाइकलिक ग्राफ़
इस प्रोसेस का हिस्सा रहे हैं.
अगर SkyFunction
कोई पास नहीं बता पाता है, तो वह SkyKeys
का अनुरोध कर सकता है
उन सभी नोड को बेहतर बना सकता है जिनकी ज़रूरत इसे अपना काम करने के लिए होती है. एक आसान उदाहरण,
एक इनपुट फ़ाइल नोड जो सिमलिंक के रूप में बदलता है: फ़ंक्शन पढ़ने की कोशिश करता है
फ़ाइल को महसूस होता है कि यह एक सिमलिंक है और इस तरह फ़ाइल सिस्टम नोड फे़च करता है
सिमलिंक के टारगेट को दिखाता है. हालांकि, अपने-आप में यह एक सिमलिंक हो सकता है,
इस मामले में, ओरिजनल फ़ंक्शन को भी अपना टारगेट फ़ेच करना होगा.
फ़ंक्शन को कोड में, इंटरफ़ेस SkyFunction
और
इसे SkyFunction.Environment
नाम के इंटरफ़ेस की मदद से उपलब्ध कराया गया है. ये
फ़ंक्शन ये काम कर सकते हैं:
env.getValue
को कॉल करके किसी दूसरे नोड के मूल्यांकन का अनुरोध करें. अगर आपने नोड उपलब्ध है, इसकी वैल्यू दिखाई जाती है. ऐसा नहीं होने पर,null
दिखाया जाता है और फ़ंक्शन को अपने-आपnull
दिखना चाहिए. बाद वाले मामले में, डिपेंडेंट नोड का आकलन होता है और फिर ओरिजनल नोड बिल्डर होता है फिर से शुरू किया गया है, लेकिन इस बार वहीenv.getValue
कॉल गैर-null
मान.env.getValues()
को कॉल करके, कई अन्य नोड के आकलन का अनुरोध करें. यह मुख्य तौर पर एक जैसा ही होता है. हालांकि, डिपेंडेंट नोड साथ-साथ मूल्यांकन किया जाएगा.- शुरू करने के दौरान कंप्यूटेशन (हिसाब लगाना) करना
- इसका खराब असर पड़ता है. उदाहरण के लिए, फ़ाइल सिस्टम में फ़ाइलें लिखना. देखभाल से जुड़ी ज़रूरतें यह समझना मुश्किल है कि दो अलग-अलग फ़ंक्शन, एक-दूसरे के चरण को पूरा करने से बचते हैं पैर की उँगलियाँ. सामान्य तौर पर, खराब असर के बारे में बताएं (जहां डेटा बेज़ल से बाहर की तरफ़ जाता है) ठीक है, दुष्प्रभाव पढ़ सकते है (जब डेटा को बिना किसी रजिस्टर की गई डिपेंडेंसी) नहीं होती हैं, क्योंकि वे रजिस्टर नहीं की गई डिपेंडेंसी हैं इस वजह से, बिल्ड में गलत तरीके से बढ़ोतरी हो सकती है.
SkyFunction
लागू करने के सही तरीके से काम करने पर, यह डेटा किसी दूसरे तरीके से ऐक्सेस नहीं करता
डिपेंडेंसी का अनुरोध करने के बजाय, जैसे कि फ़ाइल सिस्टम को सीधे पढ़कर,
क्योंकि इसके नतीजे के तौर पर Basel, फ़ाइल पर डेटा डिपेंडेंसी को रजिस्टर नहीं करता है
को पढ़ लिया गया, जिसकी वजह से गलत संख्या में बिल्ड हो गए.
जब किसी फ़ंक्शन में काम करने के लिए ज़रूरी डेटा हो, तो उसे ऐसी वैल्यू देनी चाहिए जो null
न हो
पूरा होने का संकेत देने वाला मान.
आकलन की इस रणनीति के कई फ़ायदे हैं:
- हरमैटिसिटी. अगर फ़ंक्शन, इनपुट डेटा का अनुरोध सिर्फ़ का उपयोग करने के लिए करते हैं, तो बेज़ल यह गारंटी दे सकता है कि यदि इनपुट स्थिति समान है, तो कुछ डेटा वापस मिल जाता है. अगर आकाश के सभी फलन सारणिक हैं, तो इसका मतलब कि पूरा बिल्ड भी सारणिक होगा.
- सही और सटीक बढ़ोतरी. अगर सभी फ़ंक्शन के सभी इनपुट डेटा को रिकॉर्ड कर लिया जाता है, तो Basel, नोड के सिर्फ़ उस सेट को अमान्य कर सकता है जिसकी ज़रूरत है अमान्य हो जाएगा.
- समानता. ये फ़ंक्शन एक-दूसरे से सिर्फ़ इन तरीकों से इंटरैक्ट कर सकते हैं: डिपेंडेंसी का अनुरोध करते हुए, ऐसे फ़ंक्शन जो एक-दूसरे पर निर्भर नहीं रहते, वे साथ-साथ चलने की सुविधा देता है और बेज़ेल इस बात की गारंटी दे सकता है कि नतीजा वही होगा जो उन्हें क्रम से चलाया जाता था.
बढ़ोतरी
इसकी वजह यह है कि फ़ंक्शन सिर्फ़ अन्य नोड के आधार पर, इनपुट डेटा को ऐक्सेस कर सकते हैं. इसलिए, Bagel इनपुट फ़ाइलों से आउटपुट तक का पूरा डेटा फ़्लो ग्राफ़ बना सकता है और इस जानकारी का इस्तेमाल सिर्फ़ उन नोड को फिर से बनाने के लिए करें जिन्हें असल में फिर से बनाया जाएगा: बदली गई इनपुट फ़ाइलों के सेट का रिवर्स ट्रांज़िटिव क्लोज़र.
खास तौर पर, कन्वर्ज़न बढ़ाने की दो रणनीतियां मौजूद हैं: बॉटम-अप रणनीति और सबसे ऊपर वाला विकल्प. कौनसा सबसे अच्छा है, यह डिपेंडेंसी ग्राफ़ पर निर्भर करता है ऐसा लगता है.
बॉटम-अप अमान्य होने के दौरान, ग्राफ़ बनाने और बदले गए पहले से पता होता है कि सभी नोड अमान्य हैं और वे ट्रांज़िट पर निर्भर करते हैं बदली गई फ़ाइलें. अगर एक जैसा टॉप-लेवल नोड बनाया जाएगा, तो यह बेहतर होगा फिर से. ध्यान दें कि बॉटम-अप अमान्य होने के लिए, सभी पर
stat()
चलाना ज़रूरी है पिछले बिल्ड की इनपुट फ़ाइलें डालें, ताकि यह पता लगाया जा सके कि उनमें बदलाव किया गया है या नहीं. यहinotify
या इससे मिलते-जुलते अन्य तरीकों का इस्तेमाल करके, बदली गई फ़ाइलें.टॉप-डाउन अमान्य होने के दौरान, टॉप-लेवल नोड का ट्रांज़िटिव बंद होना को चेक किया जाता है और सिर्फ़ उन नोड को रखा जाता है जिनका ट्रांज़िटिव क्लोज़िंग साफ़ होता है. यह तब बेहतर होता है, जब नोड ग्राफ़ बड़ा हो, लेकिन अगले बिल्ड के लिए सिर्फ़ इसका छोटा सबसेट: बॉटम-अप अमान्य होने से बड़ा ग्राफ़ अमान्य हो जाएगा टॉप-डाउन अमान्य होने से उलट, यह एक बड़ी समस्या होती है. दूसरे बिल्ड का ग्राफ़.
Baज़र, सिर्फ़ बॉटम-अप अमान्य होने पर ही कार्रवाई करता है.
ज़्यादा बढ़ोतरी पाने के लिए, Baज़र के पास बदलाव की काट-छांट करने का विकल्प होता है: अगर नोड अमान्य है, लेकिन दोबारा बनाने पर पता चला है कि इसकी नई वैल्यू वही है इसका पुराना मान है, वे नोड जो इस नोड में बदलाव की वजह से अमान्य हो गए थे वे "फिर से सक्रिय" हों.
उदाहरण के लिए, अगर कोई C++ फ़ाइल में टिप्पणी बदलता है, तो यह उपयोगी होता है:
इससे जनरेट की गई .o
फ़ाइल पहले जैसी ही रहेगी. इसलिए, इसे कॉल करना ज़रूरी नहीं है
को फिर से लिंक कर सकते हैं.
इंक्रीमेंटल लिंकिंग / कंपाइलेशन
इस मॉडल की मुख्य सीमा यह है कि नोड का अमान्य होना ऑल-या-नोथिंग अफ़ेयर: जब कोई डिपेंडेंसी बदलता है, तो डिपेंडेंट नोड हमेशा होता है इसे शुरुआत से बनाया गया है, भले ही एक ऐसा बेहतर एल्गोरिदम हो जो बदल जाए बदलाव के आधार पर नोड की पुरानी वैल्यू. कुछ ऐसे उदाहरण जिनमें यह उपयोगी होगा:
- इंक्रीमेंटल लिंकिंग
- जब JAR फ़ाइल में, सिंगल क्लास फ़ाइल बदल जाती है, तो ऐसा हो सकता है JAR फ़ाइल को फिर से शुरू करने के बजाय, ठीक उसी जगह बदलें.
बेज़ल इन चीज़ों को सैद्धांतिक तरीके से सपोर्ट क्यों नहीं करते दो गुना है:
- परफ़ॉर्मेंस में सीमित सुधार हुआ.
- यह पुष्टि करना मुश्किल है कि म्यूटेशन का नतीजा वही है जो एक बेहतरीन रीबिल्ड होगा. साथ ही, Google के लिए ऐसे बिल्ड को एक-एक करके पूरा करना होगा दोहराया जा सकता है.
अब तक, मुख्य खर्च को डिकोड करके, अच्छा परफ़ॉर्म किया जा सकता था और इसकी मदद से आंशिक रूप से फिर से मूल्यांकन करने की प्रक्रिया को पूरा किया जा सकता है. उदाहरण के लिए, Android ऐप्लिकेशन में, सभी क्लास को एक से ज़्यादा ग्रुप में बांटा जा सकता है. साथ ही, उन्हें अलग-अलग किया जा सकता है. इस तरह, अगर ग्रुप की क्लास में कोई बदलाव नहीं होता, तो डेक्सिंग फिर से करने की ज़रूरत नहीं है.
बेज़ेल कॉन्सेप्ट को मैप करना
यह SkyFunction
और SkyValue
कुंजी की खास जानकारी है
लागू करने की प्रोसेस: Basel, बिल्ड करने के लिए इस टूल का इस्तेमाल करती है:
- FileStateValue.
lstat()
का नतीजा. मौजूद फ़ाइलों के लिए, फ़ंक्शन, कन्वर्ज़न का पता लगाने के लिए अतिरिक्त जानकारी भी रिकॉर्ड करता है फ़ाइल से लिंक किया गया है. यह SkyFrame ग्राफ़ का निम्नतम स्तर का नोड है और इसमें कोई निर्भरता. - FileValue. ऐसे कॉन्टेंट में इस्तेमाल किया जा सकता है जो कॉन्टेंट से जुड़ी फ़िक्र करता हो या
रिज़ॉल्व किया गया पाथ शामिल है. यह संबंधित
FileStateValue
और कोई ऐसा सिमलिंक जिसे हल करना ज़रूरी है. जैसे,a/b
के लिएFileValue
रिज़ॉल्व किया गया पाथa
और रिज़ॉल्व किया गया पाथa/b
की ज़रूरत है. कॉन्टेंट बनानेFileValue
औरFileStateValue
के बीच फ़र्क़ करना ज़रूरी है, क्योंकि बाद वाले का उपयोग उन मामलों में किया जा सकता है जहां फ़ाइल का कॉन्टेंट असल ज़रूरत थी. उदाहरण के लिए, जब फ़ाइल का कॉन्टेंट काम का न हो, फ़ाइल सिस्टम ग्लब्स (जैसे किsrcs=glob(["*/*.java"])
) का आकलन करना. - DirectoryListingStateValue.
readdir()
का नतीजा. किसी ने भी पसंद नहीं कियाFileStateValue
, यह सबसे कम लेवल का नोड है और इसकी कोई निर्भरता नहीं है. - DirectoryListingValue. ऐसी किसी भी चीज़ के लिए इस्तेमाल किया जाता है जो
एक डायरेक्ट्री. यह संबंधित
DirectoryListingStateValue
पर निर्भर करता है, जैसे कि साथ ही, डायरेक्ट्री कीFileValue
इकाई शामिल है. - PackageValue. BUILD फ़ाइल का पार्स किया गया वर्शन दिखाता है. निर्भर करता है
जुड़ी हुई
BUILD
फ़ाइल काFileValue
. साथ ही, ट्रांज़िशन के साथ-साथ किसीDirectoryListingValue
जिसका इस्तेमाल पैकेज में ग्लोब को ठीक करने के लिए किया जाता है (इंटरनल तौर परBUILD
फ़ाइल का कॉन्टेंट दिखाने वाला डेटा स्ट्रक्चर). - ConfiguredTargetValue में. कॉन्फ़िगर किए गए टारगेट को दिखाता है, जो एक टपल है
उन कार्रवाइयों का सेट है जो टारगेट के विश्लेषण के दौरान जनरेट हुए हैं और
कॉन्फ़िगर किए गए डिपेंडेंट टारगेट को दी गई जानकारी. निर्भर करता है
PackageValue
संबंधित टारगेट में है,ConfiguredTargetValues
डायरेक्ट डिपेंडेंसी की सुविधा का इस्तेमाल किया जाता है. साथ ही, बिल्ड को दिखाने वाला एक खास नोड होता है कॉन्फ़िगरेशन. - ArtifactValue. यह बिल्ड में मौजूद फ़ाइल को दिखाता है. भले ही, वह सोर्स या फ़ाइल हो
आउटपुट आर्टफ़ैक्ट. आर्टफ़ैक्ट, फ़ाइलों के करीब-करीब बराबर होते हैं. साथ ही, उनका इस्तेमाल इन कामों के लिए किया जाता है
बिल्ड चरणों को पूरा करने के दौरान फ़ाइलों को रेफ़र करते हैं. सोर्स फ़ाइलें
यह संबंधित नोड के
FileValue
और आउटपुट आर्टफ़ैक्ट पर निर्भर करता है इस बात पर निर्भर करता है किActionExecutionValue
की वजह से आर्टफ़ैक्ट. - ActionExecutionValue. यह दिखाता है कि कोई कार्रवाई कैसे की जाती है. निर्भर करता है
अपनी इनपुट फ़ाइलों के
ArtifactValues
को हटा सकता है. लागू की जाने वाली कार्रवाई शामिल है में अपने SkyKey में शामिल करना है, जो इस सिद्धांत के उलट है कि SkyKeys को छोटा. ध्यान दें किActionExecutionValue
औरArtifactValue
का इस्तेमाल नहीं किया जाता, अगर लागू होने का चरण नहीं चलता.
विज़ुअल सहायता के तौर पर, इस डायग्राम में यह दिखाया गया है कि बेज़ल के बिल्ड के बाद SkyFunction लागू करना: