कुंजी-मूल्य भंडारण में वस्तुओं को समाप्त करने के लिए एल्गोरिदम क्या है?


10

मैं सोच रहा था कि वर्तमान कुंजी-मूल्य भंडारण वस्तुओं के लिए "समाप्ति की तारीख" कैसे लागू करेंगे। वर्तमान में मेरे मन में इसके 2 संस्करण हैं:

  1. वे कुछ भी नहीं करते हैं (एक्सपायर्ड डेटा रखें), और केवल जब आप चेक करते हैं, उदाहरण के लिए, कुछ कुंजी द्वारा प्राप्त करें। यहाँ समस्या यह है कि यदि आप मेमोरी में सीमित हैं, तो समयसीमा समाप्त हो जाएगी।
  2. वे "समाप्त होने के लिए सबसे पहले" प्राप्त करने में सक्षम होने के लिए अतिरिक्त डेटा संरचनाएं रखते हैं। मैं देख रहा हूँ कि इसे कुछ इस तरह से किया जा सकता है:

    storage_data = dict(key -> [value, expire_timestamp])
    expire_tree = SomeBinaryLikeTree(expire_timestamp -> [keys])
    

जवाबों:


6

कैश में समाप्त प्रविष्टियों को हटाने की समस्या बहुत कुछ कचरा संग्रह के बराबर है , संदर्भ गिनती की पूरी जटिलता शून्य से।

नासज़ा-क्लासा के लोगों ने मेमेक के लिए हे (1) एल्गोरिदम का प्रस्ताव दिया है:

ऐसा लगता है कि बहुत से लोग किसी कारण से मानते थे कि निशुल्क समाप्त प्रविष्टियों को ओ (1) में प्रदर्शित नहीं किया जा सकता है, या यहां तक ​​कि इसे ओमेगा (एन) संचालन की आवश्यकता है। एक ढेर, या अन्य प्राथमिकता कतार डेटा संरचनाओं का उपयोग करना स्पष्ट रूप से आपको O (लॉग एन) दे सकता है, लेकिन नीचे दिए गए पैच का उद्देश्य O (1) है। यह प्रत्येक सेकंड के लिए एक बाल्टी होने और समाप्ति समय को देखते हुए एक उचित बाल्टी में प्रत्येक प्रविष्टि डालकर प्राप्त किया जाता है। फिर प्रत्येक सेकंड में हम अगले बाल्टी से बस तत्वों को मुक्त करते हैं। यह स्पष्ट रूप से हे (1) परिशोधन समय है, लेकिन ऐसा हो सकता है कि आपके पास बहुत सारे तत्व हैं जो एक ही समय में समाप्त हो जाते हैं, इसलिए पैच उन परिचालनों की संख्या के लिए एक निश्चित सीमा प्रदान करता है जिन्हें आप प्रति अनुरोध करने के लिए तैयार हैं, कचरा संग्रह सुचारू चलाने के लिए।

संलग्न कोड के साथ पूरा प्रस्ताव देखें ।


धन्यवाद। मैंने "बाल्टी" समाधान पर भी एक तरह से सोचा। इसके अलावा "बाल्टी में बहुत अधिक आइटम" के साथ कोई समस्या नहीं है क्योंकि आप एल्गोरिथ्म के साथ जा सकते हैं "बाल्टी लें जिसे आपने पिछली बार नहीं लिया था, और जब आप समाप्त कर लें तो वापस प्राप्त करें"।
कोस्टिएंटिन राइबनिकोव

@k_bx: यही कारण है कि वे डबल लिंक्ड सूची का प्रस्ताव करते हैं, इसलिए आप पिछली बाल्टियों में वापस जा सकते हैं।
vartec

यदि बाल्टी कुछ सेकंड की तरह हैं, तो आपको लिंक वाली सूचियों की आवश्यकता नहीं है। पिछले जाने के लिए, आप बस कुंजी को कम करते हैं :)
कोस्टिएंटिन रब्बनिकोव

@k_bx: कुंजी कितनी घटाएं? एक क्षण? क्या होगा अगर पिछले 5 मिनट पहले पूरी तरह से खाली बाल्टी नहीं थी? 1s के कदम से 300 गुना कम?
वार्टेक

पहले सर्वर शुरू होने पर, आप कुछ मूल्य पर current_expire_bucket नामक init वैरिएबल लेते हैं। उसके बाद, आप current_expire_bucket से शुरू होने वाले क्लीनअप को चलाते हैं, जिससे वर्तमान दूसरा समाप्त होता है। सफाई समाप्त होने के बाद, आप कुछ छोटी अवधि के लिए सोते हैं। यदि सर्वर बंद हो जाता है, तो आप फिर से उसी "एक्सपायर बाल्टी" से गुजरेंगे, हाँ, लेकिन यह सर्वर स्टॉप पर ही होना चाहिए।
Kostiantyn Rybnikov

7

मुझे लगता है कि की-वैल्यू स्टोरेज बहुत बड़ी है, जो सभी केवी-जोड़े पर यह पता लगाने के लिए है कि इसकी समय सीमा समाप्त हो सकती है। मैं यह भी मानता हूं कि प्रत्येक रीड एक्सेस एक्सपायरी टाइमस्टैम्प को रीफ्रेश करता है, इसलिए केवल कुछ समय के लिए एक्सेस नहीं किए गए आइटम समाप्त हो जाते हैं।

चुनौती कुशलता से उन सभी रिकॉर्डों को ढूंढना है जो समाप्त हो सकते हैं (जब भी सफाई होती है), लेकिन यह भी कुशलतापूर्वक हर रीड एक्सेस पर एक्सपायरी टाइमस्टैम्प को ताज़ा करता है (इसलिए हमें समाप्ति के लिए उपयोग की जाने वाली संरचना में कुंजी ढूंढनी चाहिए)।

मेरा प्रस्ताव: बाल्टी में समूह expiry_timestamps; उदाहरण के लिए, यदि आइटम 8 घंटे रहते हैं, तो प्रति घंटे एक बाल्टी बनाएं। उन बाल्टी को एक लिंक्ड सूची में रखा गया है; जब समाप्ति होती है, तो पहली बाल्टी खाली हो जाती है और सूची कम हो जाती है। बाल्टियों की संख्या जीवनकाल / सफाई अंतराल है। प्रत्येक बकेट में सभी कुंजियों का एक हैशसेट होता है जिसे समाप्त किया जाना चाहिए। एक हैशसेट में सभी कुंजियों पर परिवर्तन पर्याप्त कुशल है।

रीड एक्सेस के दौरान, प्रोग्राम यह जांचता है कि वर्तमान में किस बाल्टी की कुंजी है और यह किस बाल्टी की है। ज्यादातर मामलों में, यह एक ही बाल्टी है, इसलिए आगे कोई कार्रवाई आवश्यक नहीं है। अन्यथा, पुरानी बाल्टी से कुंजी निकालें (हैश सेट से निकालना कुशल है) और इसे नई बाल्टी में डालें।

   +--------------+   +--------------+   +--------------+
-->+ Expiry 08:00 +-->+ Expiry 09:00 +-->+ Expiry 10:00 +
   | KeySet       |   | KeySet       |   | KeySet       |
   +--------------+   +--------------+   +--------------+
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.