From 0a616173ef4bcd7041336bc7a3d6e483c27bc68e Mon Sep 17 00:00:00 2001 From: John Date: Tue, 11 Jun 2019 18:39:54 +0800 Subject: [PATCH] add hash function for gview.ParseContent to improve performance in consurrent usage --- g/encoding/ghash/ghash.go | 124 ++++++++++++++++++------------------ g/os/gview/gview_doparse.go | 5 +- 2 files changed, 65 insertions(+), 64 deletions(-) diff --git a/g/encoding/ghash/ghash.go b/g/encoding/ghash/ghash.go index c2849b727..af71b2dcb 100644 --- a/g/encoding/ghash/ghash.go +++ b/g/encoding/ghash/ghash.go @@ -5,15 +5,13 @@ // You can obtain one at https://github.com/gogf/gf. // Package ghash provides some popular hash functions(uint32/uint64) in go. -// -// 常用的hash函数. package ghash // BKDR Hash Function func BKDRHash(str []byte) uint32 { - var seed uint32 = 131; // 31 131 1313 13131 131313 etc.. - var hash uint32 = 0; + var seed uint32 = 131 // 31 131 1313 13131 131313 etc.. + var hash uint32 = 0 for i := 0; i < len(str); i++ { hash = hash * seed + uint32(str[i]) } @@ -22,8 +20,8 @@ func BKDRHash(str []byte) uint32 { // BKDR Hash Function 64 func BKDRHash64(str []byte) uint64 { - var seed uint64 = 131; // 31 131 1313 13131 131313 etc.. - var hash uint64 = 0; + var seed uint64 = 131 // 31 131 1313 13131 131313 etc.. + var hash uint64 = 0 for i := 0; i < len(str); i++ { hash = hash * seed + uint64(str[i]) } @@ -32,78 +30,78 @@ func BKDRHash64(str []byte) uint64 { // SDBM Hash func SDBMHash(str []byte) uint32 { - var hash uint32 = 0; + var hash uint32 = 0 for i := 0; i < len(str); i++ { // equivalent to: hash = 65599*hash + uint32(str[i]); - hash = uint32(str[i]) + (hash << 6) + (hash << 16) - hash; + hash = uint32(str[i]) + (hash << 6) + (hash << 16) - hash } return hash } // SDBM Hash 64 func SDBMHash64(str []byte) uint64 { - var hash uint64 = 0; + var hash uint64 = 0 for i := 0; i < len(str); i++ { - // equivalent to: hash = 65599*hash + uint32(str[i]); - hash = uint64(str[i]) + (hash << 6) + (hash << 16) - hash; + // equivalent to: hash = 65599*hash + uint32(str[i]) + hash = uint64(str[i]) + (hash << 6) + (hash << 16) - hash } return hash } // RS Hash Function func RSHash(str []byte) uint32 { - var b uint32 = 378551; - var a uint32 = 63689; - var hash uint32 = 0; + var b uint32 = 378551 + var a uint32 = 63689 + var hash uint32 = 0 for i := 0; i < len(str); i++ { - hash = hash * a + uint32(str[i]); - a *= b; + hash = hash * a + uint32(str[i]) + a *= b } return hash } // RS Hash Function 64 func RSHash64(str []byte) uint64 { - var b uint64 = 378551; - var a uint64 = 63689; - var hash uint64 = 0; + var b uint64 = 378551 + var a uint64 = 63689 + var hash uint64 = 0 for i := 0; i < len(str); i++ { - hash = hash * a + uint64(str[i]); - a *= b; + hash = hash * a + uint64(str[i]) + a *= b; } return hash } // JS Hash Function func JSHash(str []byte) uint32 { - var hash uint32 = 1315423911; + var hash uint32 = 1315423911 for i := 0; i < len(str); i++ { - hash ^= ((hash << 5) + uint32(str[i]) + (hash >> 2)); + hash ^= (hash << 5) + uint32(str[i]) + (hash >> 2) } return hash } // JS Hash Function 64 func JSHash64(str []byte) uint64 { - var hash uint64 = 1315423911; + var hash uint64 = 1315423911 for i := 0; i < len(str); i++ { - hash ^= ((hash << 5) + uint64(str[i]) + (hash >> 2)); + hash ^= (hash << 5) + uint64(str[i]) + (hash >> 2) } return hash } // P. J. Weinberger Hash Function func PJWHash(str []byte) uint32 { - var BitsInUnignedInt uint32 = (4 * 8); - var ThreeQuarters uint32 = ((BitsInUnignedInt * 3) / 4); - var OneEighth uint32 = (BitsInUnignedInt / 8); - var HighBits uint32 = (0xFFFFFFFF) << (BitsInUnignedInt - OneEighth); - var hash uint32 = 0; - var test uint32 = 0; + var BitsInUnignedInt uint32 = 4 * 8 + var ThreeQuarters uint32 = (BitsInUnignedInt * 3) / 4 + var OneEighth uint32 = BitsInUnignedInt / 8 + var HighBits uint32 = (0xFFFFFFFF) << (BitsInUnignedInt - OneEighth) + var hash uint32 = 0 + var test uint32 = 0 for i := 0; i < len(str); i++ { - hash = (hash << OneEighth) + uint32(str[i]); + hash = (hash << OneEighth) + uint32(str[i]) if test = hash & HighBits; test != 0 { - hash = ((hash ^ (test >> ThreeQuarters)) & (^HighBits + 1)); + hash = (hash ^ (test >> ThreeQuarters)) & (^HighBits + 1) } } return hash @@ -111,16 +109,16 @@ func PJWHash(str []byte) uint32 { // P. J. Weinberger Hash Function 64 func PJWHash64(str []byte) uint64 { - var BitsInUnignedInt uint64 = (4 * 8); - var ThreeQuarters uint64 = ((BitsInUnignedInt * 3) / 4); - var OneEighth uint64 = (BitsInUnignedInt / 8); - var HighBits uint64 = (0xFFFFFFFFFFFFFFFF) << (BitsInUnignedInt - OneEighth); - var hash uint64 = 0; - var test uint64 = 0; + var BitsInUnignedInt uint64 = 4 * 8 + var ThreeQuarters uint64 = (BitsInUnignedInt * 3) / 4 + var OneEighth uint64 = BitsInUnignedInt / 8 + var HighBits uint64 = (0xFFFFFFFFFFFFFFFF) << (BitsInUnignedInt - OneEighth) + var hash uint64 = 0 + var test uint64 = 0 for i := 0; i < len(str); i++ { - hash = (hash << OneEighth) + uint64(str[i]); + hash = (hash << OneEighth) + uint64(str[i]) if test = hash & HighBits; test != 0 { - hash = ((hash ^ (test >> ThreeQuarters)) & (^HighBits + 1)); + hash = (hash ^ (test >> ThreeQuarters)) & (^HighBits + 1) } } return hash @@ -128,13 +126,13 @@ func PJWHash64(str []byte) uint64 { // ELF Hash Function func ELFHash(str []byte) uint32 { - var hash uint32 = 0; - var x uint32 = 0; + var hash uint32 = 0 + var x uint32 = 0 for i := 0; i < len(str); i++ { - hash = (hash << 4) + uint32(str[i]); + hash = (hash << 4) + uint32(str[i]) if x = hash & 0xF0000000; x != 0 { - hash ^= (x >> 24); - hash &= ^x + 1; + hash ^= x >> 24 + hash &= ^x + 1 } } return hash @@ -142,13 +140,13 @@ func ELFHash(str []byte) uint32 { // ELF Hash Function 64 func ELFHash64(str []byte) uint64 { - var hash uint64 = 0; - var x uint64 = 0; + var hash uint64 = 0 + var x uint64 = 0 for i := 0; i < len(str); i++ { - hash = (hash << 4) + uint64(str[i]); + hash = (hash << 4) + uint64(str[i]) if x = hash & 0xF000000000000000; x != 0 { - hash ^= (x >> 24); - hash &= ^x + 1; + hash ^= x >> 24 + hash &= ^x + 1 } } return hash @@ -156,30 +154,30 @@ func ELFHash64(str []byte) uint64 { // DJB Hash Function func DJBHash(str []byte) uint32 { - var hash uint32 = 5381; + var hash uint32 = 5381 for i := 0; i < len(str); i++ { - hash += (hash << 5) + uint32(str[i]); + hash += (hash << 5) + uint32(str[i]) } return hash } // DJB Hash Function 64 func DJBHash64(str []byte) uint64 { - var hash uint64 = 5381; + var hash uint64 = 5381 for i := 0; i < len(str); i++ { - hash += (hash << 5) + uint64(str[i]); + hash += (hash << 5) + uint64(str[i]) } return hash } // AP Hash Function func APHash(str []byte) uint32 { - var hash uint32 = 0; + var hash uint32 = 0 for i := 0; i < len(str); i++ { - if ((i & 1) == 0) { - hash ^= ((hash << 7) ^ uint32(str[i]) ^ (hash >> 3)); + if (i & 1) == 0 { + hash ^= (hash << 7) ^ uint32(str[i]) ^ (hash >> 3) } else { - hash ^= (^((hash << 11) ^ uint32(str[i]) ^ (hash >> 5)) + 1); + hash ^= ^((hash << 11) ^ uint32(str[i]) ^ (hash >> 5)) + 1 } } return hash @@ -187,12 +185,12 @@ func APHash(str []byte) uint32 { // AP Hash Function 64 func APHash64(str []byte) uint64 { - var hash uint64 = 0; + var hash uint64 = 0 for i := 0; i < len(str); i++ { - if ((i & 1) == 0) { - hash ^= ((hash << 7) ^ uint64(str[i]) ^ (hash >> 3)); + if (i & 1) == 0 { + hash ^= (hash << 7) ^ uint64(str[i]) ^ (hash >> 3) } else { - hash ^= (^((hash << 11) ^ uint64(str[i]) ^ (hash >> 5)) + 1); + hash ^= ^((hash << 11) ^ uint64(str[i]) ^ (hash >> 5)) + 1 } } return hash diff --git a/g/os/gview/gview_doparse.go b/g/os/gview/gview_doparse.go index 1ae3d750e..ece0d3ec6 100644 --- a/g/os/gview/gview_doparse.go +++ b/g/os/gview/gview_doparse.go @@ -11,6 +11,7 @@ import ( "errors" "fmt" "github.com/gogf/gf/g/container/gmap" + "github.com/gogf/gf/g/encoding/ghash" "github.com/gogf/gf/g/os/gfcache" "github.com/gogf/gf/g/os/gfile" "github.com/gogf/gf/g/os/gfsnotify" @@ -18,6 +19,7 @@ import ( "github.com/gogf/gf/g/os/gmlock" "github.com/gogf/gf/g/os/gspath" "github.com/gogf/gf/g/text/gstr" + "github.com/gogf/gf/g/util/gconv" "text/template" ) @@ -160,7 +162,8 @@ func (view *View) ParseContent(content string, params...Params) (string, error) return template.New(gCONTENT_TEMPLATE_NAME).Delims(view.delimiters[0], view.delimiters[1]).Funcs(view.funcMap) }).(*template.Template) // Using memory lock to ensure concurrent safety for content parsing. - gmlock.LockFunc("gview-parsing:content", func() { + hash := gconv.String(ghash.DJBHash64([]byte(content))) + gmlock.LockFunc("gview-parsing-content:" + hash, func() { tpl, err = tpl.Parse(content) }) if err != nil {