मैं लिंक्ड सूची और हैश तालिका के लिनक्स कर्नेल कार्यान्वयन को समझने की कोशिश कर रहा हूं। कार्यान्वयन का एक लिंक here है। मैं लिंक्ड सूची कार्यान्वयन को समझ गया। लेकिन मैं थोड़ा उलझन में हूं कि क्यों hlist (** pprev) में डबल पॉइंटर्स का उपयोग किया जा रहा है। हिस्ट्री के लिए लिंक here है। मैं समझता हूं कि हैश सूची का उपयोग हैश तालिका के कार्यान्वयन में किया जाता है क्योंकि सूची के प्रमुख को केवल एक सूचक की आवश्यकता होती है और यह स्थान बचाती है। एकल सूचक का उपयोग करके यह क्यों नहीं किया जा सकता है (बस * लिंक की गई सूची की तरह पिछला)? क्रिप्या मेरि सहायता करे।लिनक्स कर्नेल हैश सूची कार्यान्वयन में डबल पॉइंटर का उपयोग
उत्तर
कारण टिप्पणियों में से एक में पाया जा सकता:
547/*
548 * Double linked lists with a single pointer list head.
549 * Mostly useful for hash tables where the two pointer list head is
550 * too wasteful.
551 * You lose the ability to access the tail in O(1).
552 */
यदि आप * ** के बजाय pprev पिछला था, और क्योंकि हम स्मृति को बचाने के लिए कोशिश कर रहे हैं, हम में * पिछला शामिल नहीं हैं सिर, तो हमारे hlist कार्यान्वयन इस तरह दिखता है:
struct hlist_head {
struct hlist_node *first = null;
};
struct hlist_node {
struct hlist_node *next;
struct hlist_node *prev;
};
सूचना है कि prev
सूचक सिर को इंगित नहीं कर सकते, या head->first
(**pprev
के विपरीत)। यह hlist कार्यान्वयन पेचीदा हो, जैसा कि आप जब हम hlist_add_before()
लागू देखेंगे: prev
hlist_add_head()
के ऊपर imeplementation में, इंगित करने के लिए कुछ भी नहीं है
void
hlist_init(struct hlist_head *head) {
head->first = null;
}
void
hlist_add_head(struct hlist_head *head, struct hlist_node *node) {
struct hlist_node *next = head->first;
head->first = node;
node->next = next;
node->prev = NULL;
if (next) {
next->prev = node;
}
}
सूचना है कि। तो, अब जब आप hlist_add_before()
लागू यह इस तरह दिखता है:
void
hlist_add_before(struct hlist_head *head,
struct hlist_node *node,
struct hlist_next *next) {
hlist_node *prev = next->prev;
node->next = next;
node->prev = prev;
next->prev = node;
if (prev) {
prev->next = node;
} else {
head->first = node;
}
}
सूचना है कि अब हम hlist_add_before()
, जो स्टैक पर head
धकेलने के लिए एक अतिरिक्त push
अनुदेश की आवश्यकता के लिए head
में पारित करने के लिए और साथ ही जरूरत है। इसके अलावा, कार्यान्वयन में एक अतिरिक्त सशर्त जांच है, जो आगे चीजों को धीमा कर देती है।
अब **pprev
के बजाय *prev
के साथ अन्य hlist संचालन को लागू करने का प्रयास करें, और आप पाएंगे कि आपका कार्यान्वयन लिनक्स कर्नेल में जो देखा गया उससे धीमा होने वाला है।
- 1. लिनक्स कर्नेल
- 2. समस्या निवारण डबल पॉइंटर
- 3. लिनक्स कर्नेल
- 4. लिनक्स कर्नेल
- 5. लिनक्स कर्नेल: copy_from_user - पॉइंटर्स
- 6. लिनक्स कर्नेल
- 7. लिनक्स कर्नेल
- 8. लिनक्स कर्नेल स्रोत
- 9. लिनक्स सूची के लिए "पॉइंटर टू पॉइंटर" का उपयोग क्यों करता है?
- 10. लिनक्स कर्नेल
- 11. लिनक्स कर्नेल
- 12. लिनक्स कर्नेल
- 13. लिनक्स कर्नेल
- 14. लिनक्स कर्नेल
- 15. लिनक्स कर्नेल
- 16. लिनक्स कर्नेल
- 17. लिनक्स कर्नेल
- 18. लिनक्स कर्नेल मॉड्यूल में थ्रेड स्थानीय डेटा
- 19. लिनक्स कर्नेल मॉड्यूल का स्थान
- 20. रिलेशनल फिशर कर्नेल कार्यान्वयन
- 21. 32 बिट लिनक्स कर्नेल
- 22. लिनक्स में कर्नेल स्पेस से ioctl() का उपयोग कैसे करें?
- 23. सी डबल पॉइंटर
- 24. लिनक्स कर्नेल में फ़ंक्शन कॉलर
- 25. सिस्टम कॉल लिनक्स कर्नेल मॉड्यूल में अवरोधन (कर्नेल 3.5)
- 26. कॉर्पोरेट लिनक्स कर्नेल विकास
- 27. विरासत लिनक्स कर्नेल संस्करणों
- 28. अपरिवर्तनीय (डबल) लिंक्डलिस्ट का कुशल कार्यान्वयन
- 29. लिनक्स कर्नेल छवि
- 30. एंड्रॉइड कर्नेल और वेनिला लिनक्स कर्नेल
आपके उत्तर के लिए धन्यवाद। लेकिन मेरा संदेह यह है कि क्यों नहीं * पिछला और एक दोगुनी जुड़ी सूची है। इसका उपयोग करके आप दोनों तरीकों से गुजर सकते हैं। आप ओ (1) में नोड्स जोड़ और हटा सकते हैं। इस्तेमाल की गई स्मृति दोनों मामलों के लिए समान है। मैं स्पष्ट रूप से यहाँ कुछ याद कर रहा हूँ। क्या आप मेरी गलती को इंगित कर सकते हैं? – bala1486
देखें, अगर मेरा विस्तृत उत्तर मदद करता है। :) – Sudhanshu
आपको बहुत बहुत धन्यवाद ... – bala1486