2013-02-10 11 views
7

स्कैला 2.10, MurmurHash किसी कारण से बहिष्कृत किया गया है, कह रहा है कि मुझे अब MurmurHash3 का उपयोग करना चाहिए। लेकिन एपीआई अलग है, और MurmurHash3 -> असफल के लिए कोई उपयोगी स्केलडॉक्स नहीं है।MurmurHash से MurmurHash3 पर माइग्रेट करें

उदाहरण के लिए, वर्तमान कोड:

trait Foo { 
    type Bar 
    def id: Int 
    def path: Bar 

    override def hashCode = { 
    import util.MurmurHash._ 
    var h = startHash(2) 
    val c = startMagicA 
    val k = startMagicB 
    h = extendHash(h, id, c, k) 
    h = extendHash(h, path.##, nextMagicA(c), nextMagicB(k)) 
    finalizeHash(h) 
    } 
} 

मैं क्या करना होगा यह कैसे MurmurHash3 बजाय का उपयोग कर? इसे तेजी से आवंटन की आवश्यकता है, अधिमानतः आवंटन के बिना, इसलिए मैं Product, Seq, Array[Byte] या व्हाटहेवर MurmurHash3 का निर्माण नहीं करना चाहता हूं।

उत्तर

7

MurmurHash3 algorithm बदल गया था, भी संदेहास्पद एक एल्गोरिथ्म है कि मिश्रित से अपने नमक में, अनिवार्य रूप से (c और k), जो कि थोड़ा अधिक मिश्रण करता है। मूल ऑपरेशन अब mix है, जिसे आपको अपने सभी मानों पर फोल्ड करना चाहिए, जिसके बाद आपको finalizeHash (Int लंबाई के लिए तर्क भी सुविधाजनक के लिए है, अलग-अलग लंबाई के विशिष्ट संग्रह में सहायता के लिए)। यदि आप अपने अंतिम mix को mixLast से प्रतिस्थापित करना चाहते हैं, तो यह थोड़ा तेज़ है और finalizeHash के साथ अनावश्यकता को हटा देता है। यदि यह पता लगाने में आपको बहुत लंबा समय लगता है कि अंतिम मिश्रण क्या है, तो बस mix

आम तौर पर एक संग्रह के लिए आप यह इंगित करने के लिए एक अतिरिक्त मूल्य में मिश्रण करना चाहते हैं कि यह किस प्रकार का संग्रह है।

तो न्यूनतम आप

override def hashCode = finalizeHash(mixLast(id, path.##), 0) 

होगा और "आम तौर पर" आप चाहते

// Pick any string or number that suits you, put in companion object 
val fooSeed = MurmurHash3.stringHash("classOf[Foo]") 

// I guess "id" plus "path" is two things? 
override def hashCode = finalizeHash(mixLast(mix(fooSeed,id), path.##), 2) 

ध्यान दें कि लंबाई क्षेत्र वहाँ एक उच्च गुणवत्ता वाले हैश कि कि में घुलमिल देने के लिए नहीं है नंबर। महत्वपूर्ण हैश मानों के सभी मिश्रण mix के साथ किया जाना चाहिए।

+0

धन्यवाद, रेक्स। बीज पीढ़ी समझ में आता है। इसलिए 'उत्पाद' के लिए यह शायद' stringHash (productPrefix) 'होगा। –

+0

@ 0__ - यह एक उचित मूल्य होगा। यह वास्तव में एक ही सामग्री के साथ क्या हो सकता है लेकिन एक अलग पहचान के लिए उबलता है; अगर ऐसी कोई चीज़ मौजूद नहीं है (या आप इसे/उनके साथ टकराने में कोई फर्क नहीं पड़ता) तो आप वहां कुछ भी या कुछ भी नहीं डाल सकते हैं। "केवल उसी नाम और सामग्रियों की चीजों से टकराएं (जो एक 'उत्पाद' भी हैं और एक ही स्पष्ट विधि का उपयोग करके बीज चुन चुके हैं)" एक बहुत ही उचित नीति है। –

4

MurmurHash3 की source code को देखते हुए कुछ इस तरह पता चलता है:

override def hashCode = { 
    import util.hashing.MurmurHash3._ 

    val h = symmetricSeed // I'm not sure which seed to use here 
    val h1 = mix(h, id) 
    val h2 = mixLast(h1, path ##) 
    finalizeHash(h2, 2) 
} 

या (लगभग) एक लाइन में,:

import util.hashing.MurmurHash3._ 
override def hashCode = finalizeHash(mix(mix(symmetricSeed, id), path ##), 2) 
+0

अच्छा लग रहा है। मुझे लगता है कि मैं 'productSeed' का उपयोग करूंगा क्योंकि मेरा मूल कोड उत्पाद 2 हैश जनरेटर पर आधारित है। –

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