2010-12-05 10 views
5

लघु संस्करण: क्या प्रत्येक ईटीएस रिकॉर्ड को हटाने के लिए ets:foldl का उपयोग करना सुरक्षित है क्योंकि कोई उनके माध्यम से पुनरावृत्ति कर रहा है?एट्स का उपयोग करना: प्रत्येक रिकॉर्ड के लिए एक गरीब व्यक्ति के रूप में फोल्ड

मान लीजिए कि एक ईटीएस तालिका जानकारी एकत्र कर रही है और अब यह सब संसाधित करने का समय है। तालिका से एक रिकॉर्ड पढ़ा जाता है, जिसे किसी भी तरह से उपयोग किया जाता है, फिर हटा दिया जाता है। (साथ ही, मान लें कि तालिका private है, इसलिए कोई समरूपता समस्या नहीं है।)

एक और भाषा में, एक समान डेटा संरचना के साथ, आप प्रत्येक लूप का उपयोग कर सकते हैं, प्रत्येक रिकॉर्ड को संसाधित कर सकते हैं और फिर इसे हैश से हटा सकते हैं/dict/मानचित्र/जो कुछ भी। हालांकि, ets मॉड्यूल में foreach नहीं है उदा। lists करता है।

लेकिन यह काम हो सकता है:

1> ets:new(ex, [named_table]). 
ex 
2> ets:insert(ex, {alice, "high"}). 
true 
3> ets:insert(ex, {bob, "medium"}). 
true 
4> ets:insert(ex, {charlie, "low"}). 
true 
5> ets:foldl(fun({Name, Adjective}, DontCare) -> 
     io:format("~p has a ~p opinion of you~n", [Name, Adjective]), 
     ets:delete(ex, Name), 
     DontCare 
    end, notused, ex). 
bob has a "medium" opinion of you 
alice has a "high" opinion of you 
charlie has a "low" opinion of you 
notused 
6> ets:info(ex). 
[... 
{size,0}, 
...] 
7> ets:lookup(ex, bob). 
[] 

इस वरीय दृष्टिकोण है? क्या यह कम से कम सही और बग-मुक्त है?

मुझे प्रोसेस करते समय डेटा संरचना को संशोधित करने के बारे में एक सामान्य चिंता है, हालांकि ets:foldl documentation का तात्पर्य है कि foldl के अंदर रिकॉर्ड संशोधित करने के साथ ईटीएस बहुत आरामदायक है। चूंकि मैं अनिवार्य रूप से तालिका को साफ कर रहा हूं, इसलिए मैं निश्चित होना चाहता हूं।

मैं एक set तालिका के साथ Erlang R14B उपयोग कर रहा हूँ लेकिन मुझे पता है कि अगर कोई Erlang संस्करण के साथ किसी भी चेतावनियां, या तालिका के किसी भी प्रकार के रूप में अच्छी तरह से कर रहे हैं चाहते हैं। धन्यवाद!

उत्तर

8

आपका दृष्टिकोण सुरक्षित है। कारण यह सुरक्षित है कि ets:foldl/3 आंतरिक रूप से ets:first/1, ets:next/2 और ets:safe_fixtable/2 का उपयोग करें। इनकी गारंटी है कि आप चाहते हैं, अर्थात् आप तत्वों को मार सकते हैं और अभी भी पूर्ण ट्रैवर्स प्राप्त कर सकते हैं। CONCURRENCYerl -man ets अनुभाग देखें।

मेज से सभी तत्वों के अपने हटाने के लिए, वहाँ एक सरल एक लाइनर तथापि है:

ets:match_delete(ex, '_'). 

हालांकि यह आप प्रत्येक पंक्ति के लिए आईओ-स्वरूपण करना चाहते हैं चाहिए काम नहीं करता है, जिसमें foldl के साथ आपका दृष्टिकोण शायद आसान है।

+0

धन्यवाद। मैन पेज का * Concurrency * अनुभाग ठीक वही है जो मैंने याद किया था। यह स्पष्ट रूप से कहता है कि यदि आप 'safe_fixtable' का उपयोग करते हैं तो प्रत्येक ऑब्जेक्ट का दौरा किया जाता है। और हां, मेरे असली कोड में मैं निश्चित रूप से डेटा पर कुछ जटिल प्रसंस्करण कर रहा हूं इससे पहले कि इसे अनिवार्य रूप से इसे "किए गए" को इट्स के माध्यम से चिह्नित किया जाए: हटाएं। चीयर्स! – JasonSmith

1

इस तरह के मामलों के लिए हम दो टेबल के बीच वैकल्पिक होंगे या हर बार जब हम प्रसंस्करण शुरू करते हैं तो एक नई टेबल बनाएं। जब हम प्रसंस्करण चक्र शुरू करना चाहते हैं तो हम लेखकों को वैकल्पिक या नई तालिका का उपयोग शुरू करने के लिए स्विच करते हैं, फिर हम अपनी प्रसंस्करण करते हैं और पुरानी तालिका को साफ़ या हटाते हैं।

हम ऐसा इसलिए करते हैं क्योंकि अन्यथा ऐसे टुपल के समवर्ती अपडेट हो सकते हैं जिन्हें हम याद कर सकते हैं। जब हम इस तकनीक का उपयोग करते हैं तो हम उच्च आवृत्ति समवर्ती काउंटर के साथ काम कर रहे हैं।

+0

यह अच्छा है, क्योंकि यह कोड-रीलोडिंग तंत्र के समान है। मेरी प्रारंभिक चिंता - फोरच के रूप में फोल्ड का उपयोग करना - अब हल हो गया है, और काउंटरों को ठीक से बनाए रखने के तरीके के बारे में याद दिलाया जाना अच्छा है (जो मैं भी कर रहा हूं)। धन्यवाद! – JasonSmith

संबंधित मुद्दे