├── .gitignore ├── LICENSE ├── README.md ├── action └── action.go ├── bitset └── bitset.go ├── consts └── consts.go ├── convert ├── convert.go └── convert_test.go ├── crypto ├── aes │ └── aes.go ├── ecb │ └── ecb.go ├── padding.go └── rsa │ ├── code.go │ ├── rsa.go │ └── rsa_test.go ├── db ├── db.go ├── nosql │ └── nosql.go └── rdb │ └── table.go ├── debug ├── assert.go ├── backtrace.go ├── debug_test.go ├── example_test.go ├── log.go └── switch.go ├── encoding ├── gbin │ └── gbin.go ├── ini │ └── ini.go ├── json │ └── json.go ├── pak │ └── pak.go ├── tab │ └── tab.go ├── xml │ └── xml.go └── yaml │ └── yaml.go ├── errors ├── errors.go ├── handle.go ├── interface.go ├── with_id.go └── with_id_string.go ├── event ├── event.go ├── event │ ├── define.go │ └── event_server_time.go ├── event_center.go ├── factory.go ├── interface.go ├── listenerbase.go └── listenerset.go ├── factory ├── factory.go ├── factoryi.go ├── factorys.go └── reflect_test.go ├── fmt └── fmt.go ├── fs ├── file_line.go ├── file_path.go ├── file_path_test.go ├── file_size.go ├── fs.go ├── functorcmp.gp_#filehashtreenodef199.go ├── sort_slice.gp_#filehashtreenodef199.go ├── std_file_path_test.go ├── tree.gp_filehash38b3.go └── tree.gpg ├── go.mod ├── hash ├── finger_print.go ├── hash.go ├── none_hash.go └── robin.go ├── io └── io.go ├── ipc └── ipc.go ├── lang └── lang.go ├── log ├── agent.go ├── client.go ├── log.go └── server.go ├── math ├── big_int.go ├── bits_bytes.go ├── bool.go ├── cplx │ └── complex.go ├── float.go ├── number │ └── gp │ │ ├── number.gpg │ │ └── rangenumber.gp.go ├── prime │ ├── prime.go │ └── prime_data.go ├── rand │ ├── rand.go │ ├── rand.gp │ ├── rand.gp_32.go │ ├── rand.gp_64.go │ ├── rand.gpg │ └── rand_test.go ├── range_int32.go ├── range_int64.go ├── range_uint32.go ├── range_uint64.go ├── seq │ ├── sequence.go │ ├── sequence32.go │ └── sequence64.go └── uint64.go ├── net └── net.go ├── os └── os.go ├── pool ├── buffer.go └── logi │ └── pool.go ├── proto ├── any.go ├── int.go ├── integer.go └── protocol.go ├── reflect ├── reflect.go └── reflect_test.go ├── regable ├── doc.go ├── gp │ ├── factory.gp.go │ ├── gp.gpg │ ├── mapping.gp │ ├── mapping.gp.go │ └── regist.gp.go ├── reg.go ├── reg.gp ├── reg.gpg └── regable.go ├── regexp └── regexp.go ├── rpc └── rpc.go ├── sample └── stl │ └── stl.gpg ├── script └── lua │ └── lua.go ├── sort └── sort.go ├── stl ├── bit_set.go ├── deque.gp_int.go ├── doc.go ├── functorcmp.gp_#inttreenodeb60b.go ├── functorcmp.gp_int.go ├── gp │ ├── avl_tree.gp.go │ ├── bstree.gp │ ├── bstree.gp.go │ ├── deque.gp │ ├── deque.gp.go │ ├── doc.go │ ├── fibheaps.gp.go │ ├── functorcmp.gp │ ├── functorcmp.gp.go │ ├── gp.gpg │ ├── heap.gp │ ├── heap.gp.go │ ├── lfdeque.gp │ ├── lfdeque.gp.go │ ├── lfqueue.gp │ ├── lfqueue.gp.go │ ├── list.gp │ ├── list.gp.go │ ├── map.gp.go │ ├── multi_map.gp.go │ ├── multi_set.gp.go │ ├── priqueue.gp.go │ ├── queue.gp │ ├── queue.gp.go │ ├── rbtree.gp │ ├── rbtree.gp.go │ ├── ringbuffer.gp.go │ ├── set.gp.go │ ├── slist.gp │ ├── slist.gp.go │ ├── sort_slice.gp │ ├── sort_slice.gp.go │ ├── stack.gp │ ├── stack.gp.go │ ├── tree.gp │ └── tree.gp.go ├── heap.gp_int.go ├── list.gp_int.go ├── queue.gp_int.go ├── slist.gp_int.go ├── sort_slice.gp_#inttreenodeb60b.go ├── sort_slice.gp_int.go ├── stack.gp_int.go ├── stl.gpg ├── stl_test.go └── tree.gp_int.go ├── strings ├── rand.go └── rand_test.go ├── sync ├── filelock │ ├── mutex.go │ └── rwmutex.go ├── lockfree │ └── doc.go ├── spinlock.go └── spinrwlock.go ├── tasks ├── interface.go ├── task_sys.go └── time_wheel.go ├── time ├── duration.go ├── duration_test.go ├── rdtsc.go ├── stopwatch │ ├── example_test.go │ ├── options.go │ ├── single.go │ ├── stopwatch.go │ ├── stopwatch_test.go │ └── watch_duration.go ├── time_snapshot.go └── time_sys.go └── unsafe ├── string.go └── string_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gx [![GoDoc](https://godoc.org/github.com/vipally/gx?status.svg)](https://godoc.org/github.com/vipally/gx) ![Version](https://img.shields.io/badge/version-0.0.1-green.svg) 2 | gx is an extend library of golang std library 3 | ---- 4 | 5 | -------------------------------------------------------------------------------- /action/action.go: -------------------------------------------------------------------------------- 1 | package action 2 | 3 | type ActionCfg struct { 4 | Name string 5 | Type string 6 | Para string 7 | NextOk string 8 | NextFail string 9 | } 10 | 11 | type Action interface { 12 | Init(cfg *ActionCfg) 13 | Execute() bool 14 | } 15 | 16 | type ActionManager struct { 17 | } 18 | 19 | func (this *ActionManager) RegAction(cfg *ActionCfg) {} 20 | -------------------------------------------------------------------------------- /bitset/bitset.go: -------------------------------------------------------------------------------- 1 | package bitset 2 | 3 | const ( 4 | bitsOneElem = 64 5 | one uint64 = 1 6 | ) 7 | 8 | // NewBitSet create a bitset with at least capacity 9 | func NewBitSet(capacity int) *BitSet { 10 | n := (capacity + bitsOneElem - 1) / bitsOneElem 11 | return &BitSet{ 12 | b: make([]uint64, n), 13 | } 14 | } 15 | 16 | // BitSet is a set of bits 17 | type BitSet struct { 18 | b []uint64 19 | } 20 | 21 | // Add try to set a bit with 1 22 | // it return false if this bit has been set. 23 | func (bs *BitSet) Add(bit uint64) bool { 24 | n, b := bit/bitsOneElem, bit%bitsOneElem 25 | mask := one << b 26 | if bs.b[n]&mask != 0 { 27 | return false 28 | } 29 | bs.b[n] |= mask 30 | return true 31 | } 32 | 33 | // Set set a bit as 1 34 | func (bs *BitSet) Set(bit uint64) { 35 | n, b := bit/bitsOneElem, bit%bitsOneElem 36 | mask := one << b 37 | bs.b[n] |= mask 38 | } 39 | 40 | // Unset set a bit as 0 41 | func (bs *BitSet) Unset(bit uint64) { 42 | n, b := bit/bitsOneElem, bit%bitsOneElem 43 | mask := one << b 44 | bs.b[n] &= ^mask 45 | } 46 | 47 | // Has check if a bit has been set as 1 48 | func (bs BitSet) Has(bit uint64) bool { 49 | n, b := bit/bitsOneElem, bit%bitsOneElem 50 | mask := one << b 51 | return bs.b[n]&mask != 0 52 | } 53 | -------------------------------------------------------------------------------- /consts/consts.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | const ( 4 | EmptyStr = "" 5 | NewLine = "\n" 6 | CommentStr = "//" 7 | ) 8 | -------------------------------------------------------------------------------- /convert/convert.go: -------------------------------------------------------------------------------- 1 | package convert 2 | -------------------------------------------------------------------------------- /convert/convert_test.go: -------------------------------------------------------------------------------- 1 | package convert 2 | 3 | import ( 4 | "fmt" 5 | //"reflect" 6 | "testing" 7 | "unsafe" 8 | ) 9 | 10 | func TestConvert(t *testing.T) { 11 | type T struct { 12 | a int 13 | b int 14 | c int 15 | } 16 | 17 | type SliceHeader struct { 18 | addr uintptr 19 | len int 20 | cap int 21 | } 22 | 23 | tt := &T{a: 1, b: 2, c: 3} 24 | p := unsafe.Sizeof(*tt) 25 | fmt.Println(int(p)) 26 | 27 | sl := &SliceHeader{ 28 | addr: uintptr(unsafe.Pointer(tt)), 29 | len: int(p), 30 | cap: int(p), 31 | } 32 | 33 | b := *(*[]byte)(unsafe.Pointer(sl)) 34 | fmt.Println(len(b)) 35 | fmt.Println(b) 36 | 37 | b[0] = 7 38 | b[4] = 5 39 | b[8] = 8 40 | 41 | fmt.Println(tt) 42 | fmt.Println(b) 43 | // type reflect.StringHeader struct { 44 | // Data uintptr 45 | // Len int 46 | // } 47 | // type reflect.SliceHeader struct { 48 | // Data uintptr 49 | // Len int 50 | // Cap int 51 | // } 52 | } 53 | -------------------------------------------------------------------------------- /crypto/aes/aes.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "crypto/aes" 5 | "crypto/cipher" 6 | ) 7 | 8 | func PKCS7Padding(b []byte, blockSize int) []byte { 9 | size := blockSize - len(b)%blockSize 10 | buf := make([]byte, len(b)+size) 11 | copy(buf[:len(b)], b) 12 | for i := len(b); i < len(buf); i++ { 13 | buf[i] = byte(size) 14 | } 15 | return buf 16 | } 17 | 18 | func PKCS7PaddingString(str string, blockSize int) []byte { 19 | size := blockSize - len(str)%blockSize 20 | buf := make([]byte, len(str)+size) 21 | copy(buf[:len(str)], str) 22 | for i := len(str); i < len(buf); i++ { 23 | buf[i] = byte(size) 24 | } 25 | return buf 26 | } 27 | 28 | func PKCS7Unpadding(b []byte) []byte { 29 | size := int(b[len(b)-1]) 30 | return b[:len(b)-size] 31 | } 32 | 33 | type AESEncrypter struct { 34 | blockMode cipher.BlockMode 35 | blockSize int 36 | } 37 | 38 | // CBC模式/PKCS7Padding 39 | func NewAESEncrypter(key []byte) (*AESEncrypter, error) { 40 | block, err := aes.NewCipher(key) 41 | if err != nil { 42 | return nil, err 43 | } 44 | blockSize := block.BlockSize() 45 | blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) 46 | return &AESEncrypter{ 47 | blockMode: blockMode, 48 | blockSize: blockSize, 49 | }, nil 50 | } 51 | 52 | func (this *AESEncrypter) Encrypt(b []byte) []byte { 53 | padded := PKCS7Padding(b, this.blockSize) 54 | encrypted := make([]byte, len(padded)) 55 | this.blockMode.CryptBlocks(encrypted, padded) 56 | return encrypted 57 | } 58 | 59 | func (this *AESEncrypter) EncryptString(str string) []byte { 60 | padded := PKCS7PaddingString(str, this.blockSize) 61 | encrypted := make([]byte, len(padded)) 62 | this.blockMode.CryptBlocks(encrypted, padded) 63 | return encrypted 64 | } 65 | 66 | type AESDecrypter struct { 67 | blockMode cipher.BlockMode 68 | blockSize int 69 | } 70 | 71 | // CBC模式/PKCS7Padding 72 | func NewAESDecrypter(key []byte) (*AESDecrypter, error) { 73 | block, err := aes.NewCipher(key) 74 | if err != nil { 75 | return nil, err 76 | } 77 | blockSize := block.BlockSize() 78 | blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) 79 | return &AESDecrypter{ 80 | blockMode: blockMode, 81 | blockSize: blockSize, 82 | }, nil 83 | } 84 | 85 | func (this *AESDecrypter) Decrypt(b []byte) []byte { 86 | decrypted := make([]byte, len(b)) 87 | this.blockMode.CryptBlocks(decrypted, b) 88 | return PKCS7Unpadding(decrypted) 89 | } 90 | 91 | func (this *AESDecrypter) DecryptToString(b []byte) string { 92 | return string(this.Decrypt(b)) 93 | } 94 | -------------------------------------------------------------------------------- /crypto/ecb/ecb.go: -------------------------------------------------------------------------------- 1 | package ecb 2 | 3 | import ( 4 | "crypto/des" 5 | "errors" 6 | 7 | "gitee.com/vipally/gx/crypto" 8 | ) 9 | 10 | // 3DES加密 11 | func TripleDesEncrypt(origData, key []byte) ([]byte, error) { 12 | tkey := make([]byte, 24, 24) 13 | copy(tkey, key) 14 | k1 := tkey[:8] 15 | k2 := tkey[8:16] 16 | k3 := tkey[16:] 17 | 18 | block, err := des.NewCipher(k1) 19 | if err != nil { 20 | return nil, err 21 | } 22 | bs := block.BlockSize() 23 | origData = crypto.ZeroPadding(origData, bs) 24 | buf1, err := encrypt(origData, k1) 25 | if err != nil { 26 | return nil, err 27 | } 28 | buf2, err := decrypt(buf1, k2) 29 | if err != nil { 30 | return nil, err 31 | } 32 | out, err := encrypt(buf2, k3) 33 | if err != nil { 34 | return nil, err 35 | } 36 | return out, nil 37 | } 38 | 39 | // 3DES解密 40 | func TripleDesDecrypt(crypted, key []byte) ([]byte, error) { 41 | tkey := make([]byte, 24, 24) 42 | copy(tkey, key) 43 | k1 := tkey[:8] 44 | k2 := tkey[8:16] 45 | k3 := tkey[16:] 46 | buf1, err := decrypt(crypted, k3) 47 | if err != nil { 48 | return nil, err 49 | } 50 | buf2, err := encrypt(buf1, k2) 51 | if err != nil { 52 | return nil, err 53 | } 54 | out, err := decrypt(buf2, k1) 55 | if err != nil { 56 | return nil, err 57 | } 58 | out = crypto.ZeroUnPadding(out) 59 | return out, nil 60 | } 61 | 62 | //Des加密 63 | func encrypt(origData, key []byte) ([]byte, error) { 64 | if len(origData) < 1 || len(key) < 1 { 65 | return nil, errors.New("wrong data or key") 66 | } 67 | block, err := des.NewCipher(key) 68 | if err != nil { 69 | return nil, err 70 | } 71 | bs := block.BlockSize() 72 | if len(origData)%bs != 0 { 73 | return nil, errors.New("wrong padding") 74 | } 75 | out := make([]byte, len(origData)) 76 | dst := out 77 | for len(origData) > 0 { 78 | block.Encrypt(dst, origData[:bs]) 79 | origData = origData[bs:] 80 | dst = dst[bs:] 81 | } 82 | return out, nil 83 | } 84 | 85 | //Des解密 86 | func decrypt(crypted, key []byte) ([]byte, error) { 87 | if len(crypted) < 1 || len(key) < 1 { 88 | return nil, errors.New("wrong data or key") 89 | } 90 | block, err := des.NewCipher(key) 91 | if err != nil { 92 | return nil, err 93 | } 94 | out := make([]byte, len(crypted)) 95 | dst := out 96 | bs := block.BlockSize() 97 | if len(crypted)%bs != 0 { 98 | return nil, errors.New("wrong crypted size") 99 | } 100 | 101 | for len(crypted) > 0 { 102 | block.Decrypt(dst, crypted[:bs]) 103 | crypted = crypted[bs:] 104 | dst = dst[bs:] 105 | } 106 | 107 | return out, nil 108 | } 109 | -------------------------------------------------------------------------------- /crypto/padding.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import "bytes" 4 | 5 | func ZeroPadding(ciphertext []byte, blockSize int) []byte { 6 | padding := blockSize - len(ciphertext)%blockSize 7 | padtext := bytes.Repeat([]byte{0}, padding) 8 | return append(ciphertext, padtext...) 9 | } 10 | 11 | func ZeroUnPadding(origData []byte) []byte { 12 | return bytes.TrimRightFunc(origData, func(r rune) bool { 13 | return r == rune(0) 14 | }) 15 | } 16 | 17 | func PKCS5Padding(ciphertext []byte, blockSize int) []byte { 18 | padding := blockSize - len(ciphertext)%blockSize 19 | padtext := bytes.Repeat([]byte{byte(padding)}, padding) 20 | return append(ciphertext, padtext...) 21 | } 22 | 23 | func PKCS5UnPadding(origData []byte) []byte { 24 | length := len(origData) 25 | // 去掉最后一个字节 unpadding 次 26 | unpadding := int(origData[length-1]) 27 | return origData[:(length - unpadding)] 28 | } 29 | -------------------------------------------------------------------------------- /crypto/rsa/code.go: -------------------------------------------------------------------------------- 1 | package rsa 2 | 3 | import ( 4 | "crypto/sha512" 5 | "encoding/base64" 6 | "encoding/hex" 7 | 8 | "gitee.com/vipally/gx/crypto/ecb" 9 | ) 10 | 11 | var key = []byte("ac643718-9730-e711-59210") 12 | 13 | func Encode(src []byte) string { 14 | bin, err := ecb.TripleDesEncrypt(src, key) 15 | if err != nil { 16 | return "" 17 | } 18 | return base64.StdEncoding.EncodeToString(bin) 19 | } 20 | 21 | func Decode(src string) []byte { 22 | c, err := base64.StdEncoding.DecodeString(src) 23 | if err != nil { 24 | return nil 25 | } 26 | content, err := ecb.TripleDesDecrypt(c, key) 27 | if err != nil { 28 | return nil 29 | } 30 | return content 31 | } 32 | 33 | func Hash(src []byte) []byte { 34 | h := sha512.New() 35 | for i := 0; i < 5; i++ { 36 | h.Write(key) 37 | h.Write(src) 38 | h.Write(key) 39 | } 40 | return h.Sum(nil) 41 | } 42 | 43 | func EncodeString(src string) string { 44 | bin, err := ecb.TripleDesEncrypt([]byte(src), key) 45 | if err != nil { 46 | return "" 47 | } 48 | return base64.StdEncoding.EncodeToString(bin) 49 | } 50 | 51 | func DecodeString(src string) string { 52 | c, err := base64.StdEncoding.DecodeString(src) 53 | if err != nil { 54 | return "" 55 | } 56 | content, err := ecb.TripleDesDecrypt(c, key) 57 | if err != nil { 58 | return "" 59 | } 60 | return string(content) 61 | } 62 | 63 | func HashString(str string) string { 64 | h := sha512.New() 65 | for i := 0; i < 5; i++ { 66 | h.Write(key) 67 | h.Write([]byte(str)) 68 | h.Write(key) 69 | } 70 | return BytesToHexString(h.Sum(nil)) 71 | } 72 | 73 | func HexStringToBytes(s string) []byte { 74 | if b, err := hex.DecodeString(s); err == nil { 75 | return b 76 | } 77 | return nil 78 | } 79 | func BytesToHexString(b []byte) string { 80 | return hex.EncodeToString(b) 81 | } 82 | -------------------------------------------------------------------------------- /crypto/rsa/rsa.go: -------------------------------------------------------------------------------- 1 | package rsa 2 | 3 | import ( 4 | "bytes" 5 | "crypto" 6 | "crypto/rand" 7 | "crypto/rsa" 8 | "crypto/x509" 9 | "encoding/pem" 10 | "errors" 11 | ) 12 | 13 | const ( 14 | defaultHash = crypto.SHA512 15 | ) 16 | 17 | var ( 18 | errPublicKey = errors.New("public key error") 19 | errPrivateKey = errors.New("private key error") 20 | ) 21 | 22 | func MustNewClient(publicKey []byte) *RsaClient { 23 | c, err := NewClient(publicKey) 24 | if err != nil { 25 | panic(err) 26 | } 27 | return c 28 | } 29 | 30 | func NewClient(publicKey []byte) (*RsaClient, error) { 31 | block, _ := pem.Decode(publicKey) 32 | if block == nil { 33 | return nil, errPublicKey 34 | } 35 | pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) 36 | if err != nil { 37 | return nil, err 38 | } 39 | pub := pubInterface.(*rsa.PublicKey) 40 | c := &RsaClient{publicKey: pub} 41 | return c, nil 42 | } 43 | 44 | type RsaClient struct { 45 | publicKey *rsa.PublicKey 46 | } 47 | 48 | func (this *RsaClient) Encrypt(plaintext []byte) ([]byte, error) { 49 | return rsa.EncryptPKCS1v15(rand.Reader, this.publicKey, plaintext) 50 | } 51 | 52 | func (this *RsaClient) VerifyDefault(src []byte, sign []byte) error { 53 | return this.Verify(src, sign, defaultHash) 54 | } 55 | 56 | func (this *RsaClient) Verify(src []byte, sign []byte, hash crypto.Hash) error { 57 | h := hash.New() 58 | h.Write(src) 59 | hashed := h.Sum(nil) 60 | return rsa.VerifyPKCS1v15(this.publicKey, hash, hashed, sign) 61 | } 62 | 63 | func MustNewServer(privateKey []byte) *RsaServer { 64 | s, err := NewServer(privateKey) 65 | if err != nil { 66 | panic(err) 67 | } 68 | return s 69 | } 70 | 71 | func NewServer(privateKey []byte) (*RsaServer, error) { 72 | block, _ := pem.Decode(privateKey) 73 | if block == nil { 74 | return nil, errPrivateKey 75 | } 76 | priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) 77 | if err != nil { 78 | return nil, err 79 | } 80 | s := &RsaServer{privateKey: priv} 81 | return s, nil 82 | } 83 | 84 | type RsaServer struct { 85 | privateKey *rsa.PrivateKey 86 | } 87 | 88 | func (this *RsaServer) Decrypt(ciphertext []byte) ([]byte, error) { 89 | return rsa.DecryptPKCS1v15(rand.Reader, this.privateKey, ciphertext) 90 | } 91 | 92 | func (this *RsaServer) SignDefault(src []byte) ([]byte, error) { 93 | return this.Sign(src, defaultHash) 94 | } 95 | 96 | func (this *RsaServer) Sign(src []byte, hash crypto.Hash) ([]byte, error) { 97 | h := hash.New() 98 | h.Write(src) 99 | hashed := h.Sum(nil) 100 | return rsa.SignPKCS1v15(rand.Reader, this.privateKey, hash, hashed) 101 | } 102 | 103 | func GenRsaKeys(bits int) (privateKey, publicKey []byte, err error) { 104 | //generate private key 105 | priKey, _err := rsa.GenerateKey(rand.Reader, bits) 106 | if _err != nil { 107 | return "", "", _err 108 | } 109 | derStream := x509.MarshalPKCS1PrivateKey(priKey) 110 | block := &pem.Block{ 111 | Type: "private key", 112 | Bytes: derStream, 113 | } 114 | 115 | var bufPri bytes.Buffer 116 | err = pem.Encode(&bufPri, block) 117 | if err != nil { 118 | return "", "", err 119 | } 120 | privateKey = bufPri.Bytes() 121 | 122 | // generate public key from private key 123 | pubKey := &priKey.PublicKey 124 | derPkix, err := x509.MarshalPKIXPublicKey(pubKey) 125 | if err != nil { 126 | return "", "", err 127 | } 128 | block = &pem.Block{ 129 | Type: "public key", 130 | Bytes: derPkix, 131 | } 132 | var bufPub bytes.Buffer 133 | err = pem.Encode(&bufPub, block) 134 | if err != nil { 135 | return "", "", err 136 | } 137 | publicKey = bufPub.Bytes() 138 | return 139 | } 140 | -------------------------------------------------------------------------------- /db/db.go: -------------------------------------------------------------------------------- 1 | package db 2 | -------------------------------------------------------------------------------- /db/nosql/nosql.go: -------------------------------------------------------------------------------- 1 | package nosql 2 | -------------------------------------------------------------------------------- /db/rdb/table.go: -------------------------------------------------------------------------------- 1 | package rdb 2 | 3 | type Field interface { 4 | Name() string 5 | } 6 | 7 | type Table interface { 8 | Name() string 9 | Create() error 10 | Insert() error 11 | Update() error 12 | Delete() error 13 | Replace() error 14 | Truncate() error 15 | Drop() error 16 | Commit() error 17 | } 18 | 19 | type Database interface { 20 | Create() error 21 | Remove() error 22 | Use() error 23 | Name() string 24 | } 25 | 26 | type DatabaseServer interface { 27 | Name() string 28 | Ip() string 29 | Port() int 30 | Connect() error 31 | } 32 | -------------------------------------------------------------------------------- /debug/assert.go: -------------------------------------------------------------------------------- 1 | package debug 2 | 3 | func Assert(b bool) bool { 4 | if !b { 5 | panic("Assert fail\n" + Bts()) 6 | } 7 | return b 8 | } 9 | 10 | //do nothing, used to avoid compile error 11 | func Nothing(elem ...interface{}) {} 12 | -------------------------------------------------------------------------------- /debug/backtrace.go: -------------------------------------------------------------------------------- 1 | //Package debug implements some useful funcs Bt() and Bts() to view backtrace infomation for debug 2 | package debug 3 | 4 | import ( 5 | "bytes" 6 | "fmt" 7 | "runtime" 8 | ) 9 | 10 | type tFmt uint32 11 | 12 | const ( 13 | BtMe = 2 14 | BtFather = BtMe + 1 15 | ) 16 | 17 | const ( 18 | maxBtListLen = 50 19 | fmtFileLine tFmt = iota + 1 20 | fmtFunc 21 | fmtAll 22 | ) 23 | const ( 24 | strCaller = "Caller:" 25 | strCurFrame = "" 26 | ) 27 | 28 | //tell me current call frame 29 | func Bt() string { 30 | return CallStackInfo(BtMe, fmtAll, strCurFrame) 31 | } 32 | 33 | //tell me current fileline 34 | func BtFileLine() string { 35 | return CallStackInfo(BtMe, fmtFileLine, strCurFrame) 36 | } 37 | 38 | //tell me current func 39 | func BtFunc() string { 40 | return CallStackInfo(BtMe, fmtFunc, strCurFrame) 41 | } 42 | 43 | //tell me caller call frame 44 | func Caller(depth int) string { 45 | return CallStackInfo(BtFather+depth, fmtAll, strCaller) 46 | } 47 | 48 | //tell me caller fileline 49 | func CallerFileLine(depth int) string { 50 | return CallStackInfo(BtFather+depth, fmtFileLine, strCaller) 51 | } 52 | 53 | //tell me caller func 54 | func CallerFunc(depth int) string { 55 | return CallStackInfo(BtFather+depth, fmtFunc, strCaller) 56 | } 57 | 58 | //use a fast-way to build string 59 | func Bts() (bts string) { 60 | var buf bytes.Buffer 61 | var __pcs [maxBtListLen]uintptr 62 | n := runtime.Callers(BtMe, __pcs[0:]) 63 | for i := 0; i < n; i++ { 64 | _pc := __pcs[i] 65 | _f := runtime.FuncForPC(_pc) 66 | _file, _line := _f.FileLine(_pc) 67 | s := fmt.Sprintf("#%d Func{%s} File{%s : %d} pc{%0X}\n", 68 | i, _f.Name(), _file, _line, _pc) 69 | buf.WriteString(s) 70 | } 71 | 72 | return buf.String() 73 | } 74 | 75 | func CallStackInfo(nDepth int, _fmt tFmt, strhead string) (_info string) { 76 | __pc, __file, __line, __ok := runtime.Caller(nDepth) 77 | 78 | if __ok { 79 | __f := runtime.FuncForPC(__pc) 80 | switch _fmt { 81 | case fmtFileLine: 82 | _info = fmt.Sprintf("%s FileLine{%s : %d}", 83 | strhead, __file, __line) 84 | case fmtFunc: 85 | _info = fmt.Sprintf("%s Func{%s}", strhead, __f.Name()) 86 | case fmtAll: 87 | fallthrough 88 | default: 89 | _info = fmt.Sprintf("%s Func{%s} FileLine{%s : %d} pc{%0X}", 90 | strhead, __f.Name(), __file, __line, __pc) 91 | } 92 | } 93 | return 94 | } 95 | 96 | func CallStackList(nDepth int) []string { 97 | var __pcs [maxBtListLen]uintptr 98 | n := runtime.Callers(nDepth, __pcs[0:]) 99 | cs := make([]string, 0, n) 100 | for i := 0; i < n; i++ { 101 | _pc := __pcs[i] 102 | _f := runtime.FuncForPC(_pc) 103 | _file, _line := _f.FileLine(_pc) 104 | s := fmt.Sprintf("Func{%s} FileLine{%s : %d} pc{%0X}", 105 | _f.Name(), _file, _line, _pc) 106 | cs = append(cs, s) 107 | } 108 | return cs 109 | } 110 | -------------------------------------------------------------------------------- /debug/debug_test.go: -------------------------------------------------------------------------------- 1 | package debug 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | ) 7 | 8 | func TestDebug(t *testing.T) { 9 | s := Bt() 10 | sesp := " Func{github.com/vipally/gx/debug.TestDebug}" 11 | if !strings.HasPrefix(s, sesp) { 12 | t.Errorf("debug.Bt() error \n[%s]\n[%s]", s, sesp) 13 | } 14 | 15 | s = Bts() 16 | sesp = "#0 Func{github.com/vipally/gx/debug.TestDebug}" 17 | if !strings.HasPrefix(s, sesp) { 18 | t.Errorf("debug.Bts() error [%s]", s) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /debug/example_test.go: -------------------------------------------------------------------------------- 1 | package debug_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/vipally/gx/debug" 7 | ) 8 | 9 | //import "github.com/vipally/gx/debug" 10 | func ExampleBt() { 11 | //example begin 12 | fmt.Println(debug.Bt()) 13 | fmt.Println(debug.Bts()) 14 | // Output : 15 | //Func{github.com/vipally/gx/debug_test.ExampleBt} FileLine{F:/dev/gocode/src/github.com/vipally/gx/debug/example_test.go : 11} pc{42C1DE} 16 | //#0 Func{github.com/vipally/gx/debug_test.ExampleBt} File{F:/dev/gocode/src/github.com/vipally/gx/debug/example_test.go : 12} pc{42C24F} 17 | //#1 Func{testing.runExample} File{C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/testing/example.go : 100} pc{427B1C} 18 | //#2 Func{testing.RunExamples} File{C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/testing/example.go : 36} pc{427820} 19 | //#3 Func{testing.Main} File{C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/testing/testing.go : 366} pc{4286B5} 20 | //#4 Func{main.main} File{C:/DOCUME~1/ally/LOCALS~1/Temp/go-build973468619/github.com/vipally/gx/debug/_test/_testmain.go : 48} pc{401180} 21 | //#5 Func{runtime.main} File{C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/runtime/proc.c : 190} pc{4127EE} 22 | //#6 Func{runtime.goexit} File{C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist465310315/go/src/pkg/runtime/proc.c : 1223} pc{414480} 23 | } 24 | -------------------------------------------------------------------------------- /debug/log.go: -------------------------------------------------------------------------------- 1 | package debug 2 | 3 | func Log() {} 4 | -------------------------------------------------------------------------------- /debug/switch.go: -------------------------------------------------------------------------------- 1 | package debug 2 | 3 | func GetSwitch(nId int) bool { return false } 4 | func SetSwitch(nId int, state bool) bool { return false } 5 | func RegSwitch(nId int) bool { return false } 6 | -------------------------------------------------------------------------------- /encoding/gbin/gbin.go: -------------------------------------------------------------------------------- 1 | package gbin 2 | -------------------------------------------------------------------------------- /encoding/ini/ini.go: -------------------------------------------------------------------------------- 1 | // CopyRight @Ally Dale 2018 2 | // Author : Ally Dale(vipally@gmail.com) 3 | 4 | //ini file reader 5 | package ini 6 | 7 | import ( 8 | "bufio" 9 | "io" 10 | "os" 11 | "strings" 12 | ) 13 | 14 | type content struct { 15 | content string 16 | comment string 17 | } 18 | 19 | type sectionData struct { 20 | name string 21 | comment string 22 | data map[string]content 23 | } 24 | 25 | type iniData struct { 26 | comment string 27 | data map[string]sectionData 28 | } 29 | 30 | type section map[string]string 31 | 32 | type IniFile struct { 33 | sections map[string]section 34 | } 35 | 36 | func New(path string) (*IniFile, error) { 37 | f, err := os.Open(path) 38 | if err != nil { 39 | return nil, err 40 | } 41 | defer func() { 42 | f.Close() 43 | }() 44 | r := Load(f) 45 | return r, nil 46 | } 47 | 48 | func Load(f io.Reader) *IniFile { 49 | m := make(map[string]section) 50 | r := bufio.NewReader(f) 51 | sec := "" 52 | var line string 53 | var err error 54 | for err == nil { 55 | line, err = r.ReadString('\n') 56 | line = strings.TrimSpace(line) 57 | if line == "" || line[0] == ';' { 58 | continue 59 | } 60 | if line[0] == '[' && line[len(line)-1] == ']' { 61 | sec = line[1 : len(line)-1] 62 | _, ok := m[sec] 63 | if !ok { 64 | m[sec] = make(section) 65 | } 66 | continue 67 | } 68 | if sec == "" { 69 | continue 70 | } 71 | pair := strings.SplitN(line, "=", 2) 72 | val := "" 73 | if len(pair) < 1 || len(pair) > 2 { 74 | continue 75 | } 76 | if len(pair) == 2 { 77 | val = pair[1] 78 | } 79 | key := strings.TrimSpace(pair[0]) 80 | val = strings.TrimSpace(val) 81 | if key == "" { 82 | continue 83 | } 84 | m[sec][key] = val 85 | } 86 | return &IniFile{m} 87 | } 88 | 89 | func (p *IniFile) Sections() []string { 90 | s := make([]string, len(p.sections)) 91 | i := 0 92 | for k, _ := range p.sections { 93 | s[i] = k 94 | i++ 95 | } 96 | return s 97 | } 98 | 99 | func (p *IniFile) Keys(sec string) []string { 100 | m, ok := p.sections[sec] 101 | if !ok { 102 | return nil 103 | } 104 | keys := make([]string, len(m)) 105 | i := 0 106 | for key, _ := range m { 107 | keys[i] = key 108 | i++ 109 | } 110 | return keys 111 | } 112 | 113 | func (p *IniFile) GetString(sec, key, def string) string { 114 | m, ok := p.sections[sec] 115 | if !ok { 116 | return def 117 | } 118 | v, ok := m[key] 119 | if !ok { 120 | return def 121 | } 122 | return v 123 | } 124 | -------------------------------------------------------------------------------- /encoding/json/json.go: -------------------------------------------------------------------------------- 1 | package json 2 | -------------------------------------------------------------------------------- /encoding/pak/pak.go: -------------------------------------------------------------------------------- 1 | package pak 2 | -------------------------------------------------------------------------------- /encoding/tab/tab.go: -------------------------------------------------------------------------------- 1 | package tab 2 | -------------------------------------------------------------------------------- /encoding/xml/xml.go: -------------------------------------------------------------------------------- 1 | package xml 2 | -------------------------------------------------------------------------------- /encoding/yaml/yaml.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | -------------------------------------------------------------------------------- /errors/errors.go: -------------------------------------------------------------------------------- 1 | //Package errors supply some way to send and predefines string error by only passing it's ID 2 | package errors 3 | 4 | import ( 5 | "bytes" 6 | "fmt" 7 | "sync" 8 | 9 | "github.com/vipally/gx/consts" 10 | "github.com/vipally/gx/debug" 11 | ) 12 | 13 | const ( 14 | MaxRef = 100000 15 | ) 16 | 17 | type ErrMgr struct { 18 | id2Obj map[ErrorId]*ErrorDef 19 | } 20 | type ErrorDef struct { 21 | content string 22 | name string 23 | id ErrorId 24 | ref int 25 | } 26 | 27 | //type ErrorObjRaw struct { 28 | // id ErrorId 29 | //} 30 | //type ErrorObj struct { 31 | // ErrorObjRaw 32 | // para []interface{} 33 | //} 34 | 35 | //func (this *ErrorObj) Clone(para ...interface{}) *ErrorObj { 36 | // return &ErrorObj{id: this.ErrorObjRaw.id, para: para} 37 | //} 38 | 39 | //------------------------------------------------------------------- 40 | func init() { 41 | g_id2err = []string{"unknown error"} 42 | } 43 | 44 | const ( 45 | //unknown error id 46 | ERRID_UNKNOWN = errId(g_id_min) 47 | ) 48 | 49 | var ( 50 | ERRID_STD, _ = Reg("standard error") 51 | ) 52 | 53 | var ( 54 | //registered error mapping 55 | g_id2err = make([]string, 0, g_init_err) 56 | g_id2err_lock sync.RWMutex 57 | g_id_cur_max errId = g_id_invalid 58 | ) 59 | 60 | const ( 61 | g_init_err = 32 62 | g_id_invalid = g_id_min - 1 63 | g_id_min = 1001 64 | g_id_max = 9999 65 | ) 66 | 67 | type WithIdErr interface { 68 | error 69 | Id() errId 70 | } 71 | 72 | //new std error 73 | func NewError(_fmt string, _para ...interface{}) error { 74 | return fmt.Errorf(_fmt, _para...) 75 | } 76 | 77 | //func Clear() { 78 | // g_id2err_lock.Lock() 79 | // defer g_id2err_lock.Unlock() 80 | // g_id2err = nil 81 | //} 82 | 83 | func Reg(_err_name string) (id errId, err error) { 84 | g_id2err_lock.Lock() 85 | defer g_id2err_lock.Unlock() 86 | //idx := g_id_cur_max - g_id_min 87 | //id = errId(g_id_min + len(g_id2err) + 1) 88 | if g_id_cur_max < g_id_max { 89 | g_id2err = append(g_id2err, _err_name) 90 | g_id_cur_max++ 91 | id = g_id_cur_max 92 | } else { 93 | id = g_id_invalid 94 | err = fmt.Errorf("[Register] error id out of range[%d,%d] from %s", 95 | g_id_min, g_id_max, debug.Caller(0)) 96 | } 97 | return 98 | } 99 | 100 | func ShowAll() string { 101 | var buf bytes.Buffer 102 | s := fmt.Sprintf("[errors] Count:%d", g_id_cur_max-g_id_min+1) 103 | buf.WriteString(s) 104 | for id := errId(g_id_min); id <= g_id_cur_max; id++ { 105 | buf.WriteString(consts.NewLine) 106 | buf.WriteString(id.String()) 107 | } 108 | return buf.String() 109 | } 110 | 111 | type errId uint32 //never generate by other package 112 | func (cp errId) Get() (_name string, err error) { 113 | g_id2err_lock.RLock() 114 | defer g_id2err_lock.RUnlock() 115 | if err = cp.valid(); err == nil { 116 | idx := cp - g_id_min 117 | _name = g_id2err[idx] 118 | } else { 119 | _name = consts.EmptyStr 120 | } 121 | return 122 | } 123 | func (cp errId) valid() (err error) { 124 | if ok := cp >= g_id_min && cp <= g_id_cur_max; !ok { 125 | err = fmt.Errorf("invalid error id:%d", cp) 126 | } 127 | return 128 | } 129 | func (cp errId) String() string { 130 | s, err := cp.Get() 131 | if err != nil { 132 | return err.Error() 133 | } 134 | s = fmt.Sprintf("error#%d (%s)", cp, s) 135 | return s 136 | } 137 | 138 | func StdErr(e error) (err WithIdErr) { 139 | return Newf(ERRID_STD, e.Error()) 140 | } 141 | -------------------------------------------------------------------------------- /errors/handle.go: -------------------------------------------------------------------------------- 1 | package errors 2 | -------------------------------------------------------------------------------- /errors/interface.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | //id of error,an ErrorId is a predefined error type 4 | type ErrorId uint32 5 | 6 | type Error interface { 7 | error //std error interface 8 | New(para ...interface{}) Error //create another instance, call Bts()? 9 | Handle() //handle this error 10 | Id() ErrorId //Id of this error 11 | } 12 | 13 | type ErrorObj struct { 14 | Id ErrorId 15 | Para []interface{} 16 | } 17 | 18 | //regist an error 19 | func Reg(moduleId uint16, name, content string, handle Handler) ErrorId { 20 | return 0 21 | } 22 | 23 | type ErrorInfo struct { 24 | content string 25 | name string 26 | id ErrorId 27 | ref int 28 | Objs []ErrorObj 29 | } 30 | 31 | type Handler byte 32 | 33 | const ( 34 | HandleIgnore Handler = 1 << iota 35 | HandleLog 36 | HandlePrint 37 | HandlePanic 38 | HandleBts 39 | ) 40 | 41 | func (me Handler) Handle() {} 42 | -------------------------------------------------------------------------------- /errors/with_id.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | type withidErrors errId 4 | 5 | //new error only with id WithIdErr 6 | func New(_id errId) WithIdErr { 7 | return withidErrors(_id) 8 | } 9 | 10 | func (me withidErrors) Error() string { 11 | return errId(me).String() 12 | } 13 | 14 | func (me withidErrors) Id() errId { 15 | return errId(me) 16 | } 17 | -------------------------------------------------------------------------------- /errors/with_id_string.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type withidstrErrors struct { 8 | id errId 9 | err string 10 | } 11 | 12 | //new with id and string WithIdErr 13 | func Newf(_id errId, _fmt string, _para ...interface{}) WithIdErr { 14 | return &withidstrErrors{id: _id, err: fmt.Sprintf(_fmt, _para...)} 15 | } 16 | 17 | func (me *withidstrErrors) Error() string { 18 | s, err := me.id.Get() 19 | if err != nil { 20 | return err.Error() 21 | } 22 | s = fmt.Sprintf("error#%d (%s): %s", me.id, s, me.err) 23 | return s 24 | } 25 | 26 | func (me *withidstrErrors) Id() errId { 27 | return me.id 28 | } 29 | -------------------------------------------------------------------------------- /event/event.go: -------------------------------------------------------------------------------- 1 | package event 2 | -------------------------------------------------------------------------------- /event/event/define.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import ( 4 | "github.com/vipally/gx/event" 5 | ) 6 | 7 | var ( 8 | EVENT_SERVER_TIME = event.DefineEvent(1, "EVENT_SERVER_TIME") 9 | ) 10 | -------------------------------------------------------------------------------- /event/event/event_server_time.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import ( 4 | "github.com/vipally/gx/event" 5 | ) 6 | 7 | type eventServerTime struct { 8 | event.ListenerBase 9 | } 10 | -------------------------------------------------------------------------------- /event/event_center.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | type EventCenter struct { 4 | } 5 | -------------------------------------------------------------------------------- /event/factory.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | //define an event 4 | func DefineEvent(id int, name string) EventId { 5 | return 0 6 | } 7 | 8 | //register an event creater 9 | func RegEvent(creater Creater) error { 10 | return nil 11 | } 12 | -------------------------------------------------------------------------------- /event/interface.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | //event handler 4 | type Handler interface { 5 | OnEvent(para ...interface{}) error 6 | } 7 | 8 | //func event handler 9 | type HandlerFunc func(para ...interface{}) error 10 | 11 | func (f HandlerFunc) OnEvent(para ...interface{}) error { 12 | return f(para...) 13 | } 14 | 15 | type EventId uint32 16 | 17 | func (me EventId) Get() uint32 { 18 | return uint32(me) 19 | } 20 | 21 | type ListenerId uint32 22 | 23 | func (me ListenerId) Get() uint32 { 24 | return uint32(me) 25 | } 26 | 27 | //Listener creater 28 | type Creater interface { 29 | Create(listenerName string, listenerId ListenerId, handler Handler, filters ...interface{}) Listener // 30 | EventId() EventId // 31 | EventName() string // 32 | } 33 | 34 | //event listener 35 | type Listener interface { 36 | Creater //Listener must create itself 37 | Filt(para ...interface{}) bool //if Filt return true,the OnEvent will not be callback 38 | OnEvent(para ...interface{}) error //event Callback func 39 | ListenerId() ListenerId // 40 | ListenerName() string // 41 | IsEnable() bool // 42 | Enable(state bool) bool // 43 | } 44 | -------------------------------------------------------------------------------- /event/listenerbase.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | type ListenerBase struct { 4 | disable bool 5 | handler Handler 6 | listenerId ListenerId 7 | listenerName string 8 | } 9 | -------------------------------------------------------------------------------- /event/listenerset.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | type ListernerSet struct { 4 | lastId ListenerId //ID generator 5 | list []Listener 6 | } 7 | -------------------------------------------------------------------------------- /factory/factory.go: -------------------------------------------------------------------------------- 1 | package factory 2 | 3 | type Creater interface { //Factory 4 | Create(arg ...interface{}) interface{} 5 | } 6 | 7 | var ( 8 | g_factory = NewFactoryS() 9 | ) 10 | 11 | func AddCreater(typename string, creater Creater) error { 12 | return g_factory.AddCreater(typename, creater) 13 | } 14 | func RemoveCreater(typename string) error { 15 | return g_factory.RemoveCreater(typename) 16 | } 17 | 18 | func Create(typename string, arg ...interface{}) interface{} { 19 | return g_factory.Create(typename, arg...) 20 | } 21 | -------------------------------------------------------------------------------- /factory/factoryi.go: -------------------------------------------------------------------------------- 1 | package factory 2 | 3 | func NewFactoryI() *FactoryI { 4 | return &FactoryI{cmap: make(map[int]Creater)} 5 | } 6 | 7 | type FactoryI struct { 8 | cmap map[int]Creater 9 | } 10 | 11 | func (me *FactoryI) AddCreater(nType int, creater Creater) error { 12 | return nil 13 | } 14 | 15 | func (me *FactoryI) RemoveCreater(nType int) error { 16 | return nil 17 | } 18 | 19 | func (me *FactoryI) Create(nType int, arg ...interface{}) interface{} { 20 | if p, ok := me.cmap[nType]; ok { 21 | return p.Create(arg...) 22 | } 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /factory/factorys.go: -------------------------------------------------------------------------------- 1 | package factory 2 | 3 | func NewFactoryS() *FactoryS { 4 | return &FactoryS{cmap: make(map[string]Creater)} 5 | } 6 | 7 | type FactoryS struct { 8 | cmap map[string]Creater 9 | } 10 | 11 | func (me *FactoryS) AddCreater(typename string, creater Creater) error { 12 | return nil 13 | } 14 | 15 | func (me *FactoryS) RemoveCreater(typename string) error { 16 | return nil 17 | } 18 | 19 | func (me *FactoryS) Create(typename string, arg ...interface{}) interface{} { 20 | if p, ok := me.cmap[typename]; ok { 21 | return p.Create(arg...) 22 | } 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /factory/reflect_test.go: -------------------------------------------------------------------------------- 1 | package factory 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func TestReflect(t *testing.T) { 10 | //var f float64 = 1.03 11 | type Float float64 12 | var my_f Float = 1.1 13 | fmt.Println(my_f) 14 | n := reflect.New(reflect.TypeOf(my_f)) 15 | n.Elem().SetFloat(1.8) 16 | fmt.Println(n.Elem().Interface()) 17 | } 18 | -------------------------------------------------------------------------------- /fmt/fmt.go: -------------------------------------------------------------------------------- 1 | package fmt 2 | -------------------------------------------------------------------------------- /fs/file_line.go: -------------------------------------------------------------------------------- 1 | package fs 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "runtime" 7 | "strings" 8 | ) 9 | 10 | const ( 11 | thisFile = "github.com/vipally/gx/fs/file_line.go" 12 | myCallerFrame = 1 //1 means my caller it self 13 | ) 14 | 15 | var ( 16 | gGoPath = goPath() 17 | gWorkPath = workPath() 18 | ) 19 | 20 | //the caller's file/line info 21 | func FileLine() (file string, line int) { 22 | if _, __file, __line, __ok := runtime.Caller(myCallerFrame); __ok { 23 | file, line = __file, __line 24 | } 25 | return 26 | } 27 | 28 | //the caller's file/line relate GoPath 29 | func RelateFileLine() (file string, line int) { 30 | if _, __file, __line, __ok := runtime.Caller(myCallerFrame); __ok { 31 | file, line = RelateGoPath(__file), __line 32 | } 33 | return 34 | } 35 | 36 | //the caller's func path 37 | func Func() (f string) { 38 | if __pc, _, __line, __ok := runtime.Caller(myCallerFrame); __ok { 39 | __f := runtime.FuncForPC(__pc) 40 | f = fmt.Sprintf("%s : %d", __f.Name(), __line) 41 | } 42 | return 43 | } 44 | 45 | func goPath() (p string) { 46 | //get GoPath 47 | s := os.Getenv("GOPATH") 48 | if ss := strings.Split(s, ";"); ss != nil && len(ss) > 0 { 49 | p = FormatPath(ss[0] + "/src/") 50 | } 51 | return 52 | } 53 | 54 | //GoPath 55 | func GoPath() string { 56 | return gGoPath 57 | } 58 | 59 | func workPath() (p string) { 60 | if dir, err := os.Getwd(); err == nil { 61 | p = dir 62 | } else { 63 | panic(err) 64 | } 65 | return 66 | } 67 | 68 | //working path 69 | func WorkPath() (dir string) { 70 | return gWorkPath 71 | } 72 | 73 | //path related to GoPath 74 | func RelateGoPath(filePath string) string { 75 | return FilePath(filePath).RelateGoPath().String() 76 | } 77 | 78 | //path related to WorkPath 79 | func RelateWorkPath(filePath string) string { 80 | return FilePath(filePath).RelateWorkPath().String() 81 | } 82 | 83 | //path related to root 84 | func RelatePath(filePath, root string) string { 85 | return FilePath(filePath).Relate(root).String() 86 | } 87 | 88 | //temp dir 89 | func TempDir() string { 90 | return FormatPath(os.TempDir()) 91 | } 92 | 93 | func Chdir(filePath string) (err error) { 94 | if err = os.Chdir(FormatPath(filePath)); err == nil { 95 | gWorkPath = workPath() //refresh this lib 96 | } 97 | return 98 | } 99 | 100 | //to format "\\" with "/" 101 | func FormatPath(filePath string) string { 102 | return FilePath(filePath).String() 103 | } 104 | -------------------------------------------------------------------------------- /fs/file_path_test.go: -------------------------------------------------------------------------------- 1 | package fs 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "syscall" 7 | "testing" 8 | ) 9 | 10 | func TestFilePath(t *testing.T) { 11 | // _path := "d:/base\\debug/app.go" 12 | // fp := FilePath(_path) 13 | // fmt.Println(fp) 14 | // fp.Set("c:/db\\ab.txt") 15 | // fmt.Println(fp) 16 | 17 | // var s FileSize = math.MaxUint64 - math.MaxUint64 + 2000000000000000 // - 17999999999999999999 // 1024 * 1024 * 1024 * 1024 * 1024 * 1024 18 | // fmt.Println(s) 19 | // s.Set(1024) 20 | // fmt.Println(s) 21 | 22 | // fmt.Println(FileLine()) 23 | // fmt.Println(Func()) 24 | // fmt.Println(GoPath()) 25 | // f, _ := FileLine() 26 | // fmt.Println(f) 27 | // fmt.Println(RelateGoPath(f)) 28 | // fmt.Println(RelatePath(f, "E:/dev")) 29 | // fmt.Println(filepath.Clean("E:/dev/../app/hello\\x.txt")) 30 | p := FilePath("E:/temp") 31 | //p := FilePath("//localhost/share/share_dir/share_file_in_share_dir.txt") 32 | //fmt.Println(p.Rename("share_file_in_share_dir2.txt")) 33 | //fmt.Println(p.Truncate(20)) 34 | // fmt.Println(p.Statistic()) 35 | // fmt.Println(FilePath(WorkPath()).RelateGoPath()) 36 | // fmt.Println(WorkPath()) 37 | // fmt.Println(FilePath("E:/dev/gocode/trunk/src/github.com/vipally/gx/fs/x/h.txt").RelateWorkPath()) 38 | // fmt.Println(WorkPath()) 39 | if n, e := p.Hash(NONE, ""); e == nil { 40 | l := n.All() 41 | for _, v := range l { 42 | fmt.Println(v.Hash, v.Path, v.Size) 43 | } 44 | // { 45 | // v := n.Visitor() 46 | // for v.Next() { 47 | // g := v.Get() 48 | // fmt.Println(g.Hash, g.Path, g.Size) 49 | // } 50 | // } 51 | fmt.Println("visiting...") 52 | { 53 | for v := n.Visitor(); v.Prev(); { 54 | g := v.Get() 55 | fmt.Println(g.Hash, g.Path, g.Size) 56 | } 57 | } 58 | } else { 59 | fmt.Println(e) 60 | } 61 | 62 | // fmt.Println(os.Getegid(), os.Geteuid(), os.Getpid(), os.Getpagesize()) 63 | // fmt.Println(os.Hostname()) 64 | // p.Statistic() 65 | 66 | // dirs := []string{"e:/", "//localhost/share/", "\\\\localhost\\share\\", "\\\\localhost\\share\\share_dir\\xx.txt\\yy\\zz\\aa.txt", "c:/;d:/;e:"} 67 | // for _, v := range dirs { 68 | // fp := FilePath(v) 69 | // fmt.Println(v, fp, fp.StringSys()) 70 | // fmt.Println(fp.SplitList()) 71 | // list := fp.SplitAll() 72 | // fmt.Println(list, Joins(list...)) 73 | // fmt.Println(fp.Join("a/b/hello.txt")) 74 | // } 75 | 76 | } 77 | 78 | func TestFileLock(t *testing.T) { 79 | _path := "e:/url.txt" 80 | _, err := syscall.CreateFile(syscall.StringToUTF16Ptr(_path), 81 | syscall.GENERIC_READ|syscall.GENERIC_WRITE, 82 | syscall.FILE_SHARE_READ, 83 | nil, 84 | syscall.OPEN_EXISTING, 85 | syscall.FILE_ATTRIBUTE_NORMAL|syscall.FILE_FLAG_OVERLAPPED, 86 | 0) 87 | if err != nil { 88 | fmt.Println("e0", err) 89 | return 90 | } 91 | // f := os.NewFile(uintptr(h), _path) 92 | // defer func() { 93 | // if err != nil { 94 | // f.Close() 95 | // } 96 | // }() 97 | f0, e0 := os.OpenFile(_path, os.O_CREATE, os.ModePerm) 98 | f1, e1 := os.Open(_path) 99 | //f.Close() 100 | f2, e2 := os.Open(_path) 101 | if e0 == nil { 102 | f0.Close() 103 | } else { 104 | fmt.Println("e0", e0) 105 | } 106 | if e1 == nil { 107 | f1.Close() 108 | } else { 109 | fmt.Println("e1", e1) 110 | } 111 | if e2 == nil { 112 | f2.Close() 113 | } else { 114 | fmt.Println("e2", e2) 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /fs/file_size.go: -------------------------------------------------------------------------------- 1 | package fs 2 | 3 | import "fmt" 4 | 5 | const ( 6 | kBits = 10 7 | kb = 1 << kBits 8 | ) 9 | 10 | var bytesNames = []string{"B", "KB", "MB", "GB", "TB", "PB", "EB"} //max16EB ignore the next: "ZB", "YB", "BB" 11 | 12 | //file-size object 13 | type FileSize uint64 14 | 15 | //show file-size 16 | func (me FileSize) String() string { 17 | m64 := uint64(me) 18 | i, b := 0, uint64(0) 19 | for ; i < len(bytesNames); i, b = i+1, b+kBits { 20 | if (m64 >> b) < kb { 21 | break 22 | } 23 | } 24 | m := 1 << b 25 | d := float64(me) / float64(m) 26 | return fmt.Sprintf("%.3f%s", d, bytesNames[i]) 27 | } 28 | 29 | //to uint64 30 | func (me FileSize) N() uint64 { 31 | return uint64(me) 32 | } 33 | 34 | //from uint64 35 | func (this *FileSize) Set(val uint64) { 36 | *this = FileSize(val) 37 | } 38 | -------------------------------------------------------------------------------- /fs/fs.go: -------------------------------------------------------------------------------- 1 | //package fs implements file-system related path and file operations 2 | package fs 3 | 4 | import ( 5 | "os" 6 | "path" 7 | ) 8 | 9 | const ( 10 | FsDir FsOption = 1 << iota //dir 11 | FsFile //file 12 | 13 | FsFullPath //full path 14 | FsDeep //deep collect 15 | FsLeaf //leaf items 16 | 17 | FsNone = FsOption(0) 18 | FsAll = FsDir | FsFile 19 | ) 20 | 21 | type FsOption uint 22 | 23 | func (me FsOption) has(opt FsOption) bool { 24 | return opt != 0 && me&opt == opt 25 | } 26 | func (me FsOption) has_any(opt FsOption) bool { 27 | return opt != 0 && me&opt != 0 28 | } 29 | func (me FsOption) choose_name(full_name, name string) string { 30 | if me.has(FsFullPath) { 31 | return full_name 32 | } else { 33 | return name 34 | } 35 | } 36 | 37 | func GetLeafDirs(dir string) (subs []string, err error) { 38 | return CollectSubs(dir, FsDir|FsLeaf|FsFullPath) 39 | } 40 | 41 | func GetSubDirs(dir string) (subs []string, err error) { 42 | return CollectSubs(dir, FsDir) 43 | } 44 | 45 | func GetSubFiles(dir string) (subs []string, err error) { 46 | return CollectSubs(dir, FsFile) 47 | } 48 | 49 | func GetSubs(dir string) (subs []string, err error) { 50 | return CollectSubs(dir, FsAll) 51 | } 52 | 53 | func GetDeepFiles(dir string) (subs []string, err error) { 54 | return CollectSubs(dir, FsFile|FsDeep) 55 | } 56 | 57 | func CollectSubs(dir string, opt FsOption) (subs []string, err error) { 58 | if _f, err := os.Open(dir); err == nil { 59 | defer _f.Close() 60 | if _subs, err := _f.Readdir(0); err == nil { 61 | _has_sub_dir := false 62 | for _, _v := range _subs { 63 | _sub_name := _v.Name() 64 | _fullsubname := Joins(dir, _sub_name) 65 | 66 | if _v.IsDir() { 67 | if _sub_name == "." || _sub_name == ".." { 68 | continue 69 | } 70 | _has_sub_dir = true 71 | 72 | if opt.has(FsDir) && !opt.has(FsLeaf) { //if contain a sub dir, it's not leaf dir 73 | subs = append(subs, opt.choose_name(_fullsubname, _sub_name)) 74 | } 75 | if opt.has_any(FsDeep | FsLeaf) { 76 | if _r, err := CollectSubs(_fullsubname, opt); err == nil { 77 | subs = append(subs, _r...) 78 | } else { 79 | return nil, err 80 | } 81 | } 82 | } else { 83 | if opt.has(FsFile) { 84 | subs = append(subs, opt.choose_name(_fullsubname, _sub_name)) 85 | } 86 | } 87 | } 88 | if !_has_sub_dir && opt.has(FsLeaf|FsDir) { 89 | subs = append(subs, opt.choose_name(dir, FileName(dir))) 90 | } 91 | } 92 | } 93 | return 94 | } 95 | 96 | func Create(_dir string) error { 97 | _parent := _dir //Dir(_dir) 98 | if f, e := os.Open(_dir); e == nil { 99 | if e2 := Create(_parent); e2 == nil { 100 | _, e2 = os.Create(_parent) 101 | return e2 102 | } else { 103 | return e2 104 | } 105 | } else { 106 | f.Close() 107 | } 108 | return nil 109 | } 110 | 111 | func Split(file_path string) (_path, _file string) { 112 | return path.Split(file_path) 113 | } 114 | 115 | //func Path(file_path string) (path string) { 116 | // path, _ = Split(file_path) 117 | // return 118 | //} 119 | 120 | func FileName(file_path string) (file string) { 121 | _, file = Split(file_path) 122 | return 123 | } 124 | 125 | //func FileBase(file_path string) (file string) { 126 | // full := FileName(file_path) 127 | // ext := FileExt(file_path) 128 | // file = strings.TrimSuffix(full, ext) 129 | // return 130 | //} 131 | 132 | //func FileExt(file_path string) (ext string) { 133 | // return path.Ext(file_path) 134 | //} 135 | 136 | //func Dir(file_path string) (dir string) { 137 | // return path.Dir(file_path) 138 | //} 139 | 140 | //func IsAbs(file_path string) (b bool) { 141 | // if strings.HasPrefix(file_path, "/") || strings.Contains(file_path, ":/") { //windows D:/... linux /root/... 142 | // return true 143 | // } 144 | // return path.IsAbs(file_path) 145 | //} 146 | 147 | //func Join(elem ...string) (file_path string) { 148 | // return path.Join(elem...) 149 | //} 150 | 151 | //func Match(pattern, name string) (matched bool, err error) { 152 | // return path.Match(pattern, name) 153 | //} 154 | -------------------------------------------------------------------------------- /fs/functorcmp.gp_#filehashtreenodef199.go: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // 3 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 4 | // 5 | // This file was auto-generated by tool [github.com/vipally/gogp] 6 | // Last update at: [Sat Apr 01 2017 22:48:09] 7 | // Generate from: 8 | // [github.com/vipally/gx/stl/gp/functorcmp.gp] 9 | // [github.com/vipally/gx/fs/tree.gpg] [_tree_sort_slice] 10 | // 11 | // Tool [github.com/vipally/gogp] info: 12 | // CopyRight 2016 @Ally Dale. All rights reserved. 13 | // Author : Ally Dale(vipally@gmail.com) 14 | // Blog : http://blog.csdn.net/vipally 15 | // Site : https://github.com/vipally 16 | // BuildAt : 17 | // Version : 3.0.0.final 18 | // 19 | /////////////////////////////////////////////////////////////////// 20 | 21 | //this file is used to import by other gp files 22 | //it cannot use independently, simulation C++ stl functors 23 | 24 | package fs 25 | 26 | const ( 27 | CMPLesser = iota //default 28 | CMPGreater 29 | ) // 30 | 31 | //cmp object, zero is Lesser 32 | type CmpFileHash byte 33 | 34 | const ( 35 | CmpFileHashLesser CmpFileHash = CMPLesser 36 | CmpFileHashGreater CmpFileHash = CMPGreater 37 | ) 38 | 39 | //create cmp object by name 40 | func CreateCmpFileHash(cmpName string) (r CmpFileHash) { 41 | r = CmpFileHashLesser.CreateByName(cmpName) 42 | return 43 | } 44 | 45 | //uniformed global function 46 | func (me CmpFileHash) F(left, right *FileHashTreeNode) (ok bool) { 47 | switch me { 48 | case CMPLesser: 49 | ok = me.less(left, right) 50 | case CMPGreater: 51 | ok = me.great(left, right) 52 | } 53 | return 54 | } 55 | 56 | //Lesser object 57 | func (me CmpFileHash) Lesser() CmpFileHash { return CMPLesser } 58 | 59 | //Greater object 60 | func (me CmpFileHash) Greater() CmpFileHash { return CMPGreater } 61 | 62 | //show as string 63 | func (me CmpFileHash) String() (s string) { 64 | switch me { 65 | case CMPLesser: 66 | s = "Lesser" 67 | case CMPGreater: 68 | s = "Greater" 69 | default: 70 | s = "error cmp value" 71 | } 72 | return 73 | } 74 | 75 | //create by bool 76 | func (me CmpFileHash) CreateByBool(bigFirst bool) (r CmpFileHash) { 77 | if bigFirst { 78 | r = CMPGreater 79 | } else { 80 | r = CMPLesser 81 | } 82 | return 83 | } 84 | 85 | //create cmp object by name 86 | func (me CmpFileHash) CreateByName(cmpName string) (r CmpFileHash) { 87 | switch cmpName { 88 | case "": //default Lesser 89 | fallthrough 90 | case "Lesser": 91 | r = CMPLesser 92 | case "Greater": 93 | r = CMPGreater 94 | default: //unsupport name 95 | panic(cmpName) 96 | } 97 | return 98 | } 99 | 100 | //lesser operation 101 | func (me CmpFileHash) less(left, right *FileHashTreeNode) (ok bool) { 102 | 103 | ok = left.Less(right) 104 | 105 | return 106 | } 107 | 108 | //Greater operation 109 | func (me CmpFileHash) great(left, right *FileHashTreeNode) (ok bool) { 110 | 111 | ok = right.Less(left) 112 | 113 | return 114 | } 115 | -------------------------------------------------------------------------------- /fs/sort_slice.gp_#filehashtreenodef199.go: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // 3 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 4 | // 5 | // This file was auto-generated by tool [github.com/vipally/gogp] 6 | // Last update at: [Sat Apr 01 2017 22:48:09] 7 | // Generate from: 8 | // [github.com/vipally/gx/stl/gp/sort_slice.gp] 9 | // [github.com/vipally/gx/fs/tree.gpg] [_tree_sort_slice] 10 | // 11 | // Tool [github.com/vipally/gogp] info: 12 | // CopyRight 2016 @Ally Dale. All rights reserved. 13 | // Author : Ally Dale(vipally@gmail.com) 14 | // Blog : http://blog.csdn.net/vipally 15 | // Site : https://github.com/vipally 16 | // BuildAt : 17 | // Version : 3.0.0.final 18 | // 19 | /////////////////////////////////////////////////////////////////// 20 | 21 | //this file define a template type for sort 22 | 23 | package fs 24 | 25 | import "sort" 26 | 27 | //////////////////////////////////////////////////////////////////////////////// 28 | 29 | var gFileHashSortSliceGbl struct { 30 | cmp CmpFileHash 31 | } 32 | 33 | func init() { 34 | gFileHashSortSliceGbl.cmp = gFileHashSortSliceGbl.cmp.CreateByName("") 35 | } 36 | 37 | //new sort object 38 | func NewFileHashSortSlice(capacity int) *FileHashSortSlice { 39 | p := &FileHashSortSlice{} 40 | p.Init(capacity) 41 | return p 42 | } 43 | 44 | //sort slice 45 | type FileHashSortSlice struct { 46 | d []*FileHashTreeNode 47 | } 48 | 49 | //init 50 | func (this *FileHashSortSlice) Init(capacity int) { 51 | this.d = make([]*FileHashTreeNode, 0, capacity) 52 | } 53 | 54 | //sort 55 | func (this *FileHashSortSlice) Sort() { 56 | sort.Sort(this) 57 | } 58 | 59 | //data buffer 60 | func (this *FileHashSortSlice) Buffer() []*FileHashTreeNode { 61 | return this.d 62 | } 63 | 64 | //push 65 | func (this *FileHashSortSlice) Push(v *FileHashTreeNode) int { 66 | this.d = append(this.d, v) 67 | return this.Len() 68 | } 69 | 70 | //insert 71 | func (this *FileHashSortSlice) Insert(v *FileHashTreeNode, idx int) int { 72 | if idx >= 0 && idx < this.Len() { 73 | right := this.d[idx+1:] 74 | this.d = append(this.d[:idx], v) 75 | this.d = append(this.d, right...) 76 | } else { 77 | this.d = append(this.d, v) 78 | } 79 | return this.Len() 80 | } 81 | 82 | //remove 83 | func (this *FileHashSortSlice) Remove(idx int) (r *FileHashTreeNode, ok bool) { 84 | if r, ok = this.Get(idx); ok { 85 | right := this.d[idx+1:] 86 | this.d = append(this.d[:idx], right...) 87 | } 88 | return 89 | } 90 | 91 | //pop 92 | func (this *FileHashSortSlice) Pop() (r *FileHashTreeNode, ok bool) { 93 | if ok = len(this.d) > 0; ok { 94 | r = (this.d)[len(this.d)-1] 95 | } 96 | this.d = (this.d)[:len(this.d)-1] 97 | return 98 | } 99 | 100 | //get 101 | func (this *FileHashSortSlice) Get(idx int) (r *FileHashTreeNode, ok bool) { 102 | if ok = idx >= 0 && idx < this.Len(); ok { 103 | r = this.d[idx] 104 | } 105 | return 106 | } 107 | 108 | //must get 109 | func (this *FileHashSortSlice) MustGet(idx int) (r *FileHashTreeNode) { 110 | ok := false 111 | if r, ok = this.Get(idx); !ok { 112 | panic(idx) 113 | } 114 | return 115 | } 116 | 117 | //len 118 | func (this *FileHashSortSlice) Len() int { 119 | return len(this.d) 120 | } 121 | 122 | //sort by Hash decend,the larger one first 123 | func (this *FileHashSortSlice) Less(i, j int) (ok bool) { 124 | l, r := (this.d)[i], (this.d)[j] 125 | return gFileHashSortSliceGbl.cmp.F(l, r) 126 | } 127 | 128 | //swap 129 | func (this *FileHashSortSlice) Swap(i, j int) { 130 | (this.d)[i], (this.d)[j] = (this.d)[j], (this.d)[i] 131 | } 132 | -------------------------------------------------------------------------------- /fs/std_file_path_test.go: -------------------------------------------------------------------------------- 1 | package fs 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path" 7 | "path/filepath" 8 | "testing" 9 | ) 10 | 11 | func __TestStdFilePath(t *testing.T) { 12 | 13 | dirs := []string{"e:/", "//localhost/share/", "\\\\localhost\\share\\", "https://github.com/vipally/../allydale/"} 14 | for _, v := range dirs { 15 | dirPath := path.Clean(v) 16 | dirFilePath := filepath.Clean(v) 17 | fmt.Printf("path.Clean(%s)=%s\n", v, dirPath) 18 | fmt.Printf("filepath.Clean(%s)=%s\n", v, dirFilePath) 19 | if e := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error { 20 | if err == nil { 21 | if info.IsDir() { 22 | //fmt.Printf("walk %s name=%s size=%d\n", path, info.Name(), info.Size()) 23 | } 24 | } else { 25 | fmt.Println(err) 26 | } 27 | return err 28 | }); e != nil { 29 | //panic(e) 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /fs/tree.gpg: -------------------------------------------------------------------------------- 1 | ;this is exactlly an ini file 2 | ;this is an example of gogp reverse usage: generate .gp file form .gpg and .go file, sectionname must be GOGP_REVERSE 3 | ;go_reverse section is used to do the next thing, gen .go file from .gpg and .gp file 4 | [tree_filehash] 5 | ;GOGP_Ignore=true 6 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/tree 7 | ;GOGP_GpFilePath=../stl/gp/tree 8 | GOGP_HasCmpFunc=true 9 | GOGP_DefaultCmpType=Greater 10 | GOGP_SectionSortSlice=_tree_sort_slice 11 | PACKAGE=package fs 12 | VALUE_TYPE=FileHash 13 | GLOBAL_NAME_PREFIX=FileHash 14 | 15 | [_tree_sort_slice] 16 | GOGP_Ignore=true 17 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/sort_slice 18 | GOGP_HasCmpFunc=true 19 | PACKAGE=package fs 20 | VALUE_TYPE=*FileHashTreeNode 21 | GLOBAL_NAME_PREFIX=FileHash 22 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gxlb/gx 2 | 3 | go 1.16 4 | -------------------------------------------------------------------------------- /hash/finger_print.go: -------------------------------------------------------------------------------- 1 | package hash 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "hash" 7 | ) 8 | 9 | //finger print hash algorithm, use md5+sha1+crc64 10 | type Fingerprint struct { 11 | hs1, hs2, hs3 hash.Hash 12 | size int64 //size wrote 13 | } 14 | 15 | func NewFingerprint() *Fingerprint { 16 | fp := &Fingerprint{} 17 | fp.hs1 = MD5.New() 18 | fp.hs2 = SHA1.New() 19 | fp.hs3 = CRC64.New() 20 | return fp 21 | } 22 | 23 | func (this *Fingerprint) Hash() hash.Hash { 24 | return this 25 | } 26 | 27 | func (this *Fingerprint) Resetsize(size int64) { 28 | this.size = size 29 | } 30 | 31 | func (this *Fingerprint) String() string { 32 | p := fmt.Sprintf("%012x-%x-%x-%x", this.size&0xFFFFFFFFFFFF, this.hs1.Sum(nil)[4:10], this.hs2.Sum(nil)[7:13], this.hs3.Sum(nil)[1:7]) 33 | return p 34 | } 35 | 36 | func (this *Fingerprint) Write(p []byte) (n int, err error) { 37 | if n, err = this.hs1.Write(p); err != nil { 38 | return 39 | } 40 | if n, err = this.hs2.Write(p); err != nil { 41 | return 42 | } 43 | if n, err = this.hs3.Write(p); err != nil { 44 | return 45 | } 46 | this.size += int64(n) 47 | return 48 | } 49 | 50 | func (this *Fingerprint) Sum(b []byte) []byte { 51 | buf := bytes.NewBuffer(nil) 52 | size := uint64(this.size & 0xFFFFFFFFFFFF) 53 | for i := uint(6); i > 0; i-- { 54 | buf.WriteByte(byte(size >> ((i - 1) * 8) & 0xff)) 55 | } 56 | buf.Write(this.hs1.Sum(nil)[4:10]) 57 | buf.Write(this.hs2.Sum(nil)[7:13]) 58 | buf.Write(this.hs3.Sum(nil)[1:7]) 59 | return buf.Bytes() 60 | } 61 | 62 | func (this *Fingerprint) Reset() { 63 | this.hs1.Reset() 64 | this.hs2.Reset() 65 | this.hs3.Reset() 66 | } 67 | 68 | func (this *Fingerprint) Size() int { 69 | return int(this.size) 70 | } 71 | 72 | func (this *Fingerprint) BlockSize() int { 73 | return 24 74 | } 75 | -------------------------------------------------------------------------------- /hash/hash.go: -------------------------------------------------------------------------------- 1 | //package hash uniform the interface to create a hash objet 2 | package hash 3 | 4 | import ( 5 | "crypto/md5" 6 | "crypto/sha1" 7 | "crypto/sha256" 8 | "crypto/sha512" 9 | "fmt" 10 | "hash" 11 | "hash/crc32" 12 | "hash/crc64" 13 | ) 14 | 15 | type HashMethod uint 16 | 17 | const ( 18 | NONE HashMethod = iota 19 | MD5 20 | SHA1 21 | SHA256 22 | SHA512 23 | CRC32 24 | CRC64 25 | FINGERPRINT //finger print, use md5+sha1+crc64 26 | ) 27 | 28 | var ( 29 | gCrc6ISO4Table = crc64.MakeTable(crc64.ISO) 30 | ) 31 | 32 | //create a hash object 33 | func (me HashMethod) New() (h hash.Hash) { 34 | switch me { 35 | case MD5: 36 | h = md5.New() 37 | case SHA1: 38 | h = sha1.New() 39 | case SHA256: 40 | h = sha256.New() 41 | case SHA512: 42 | h = sha512.New() 43 | case CRC32: 44 | h = crc32.NewIEEE() 45 | case CRC64: 46 | h = crc64.New(gCrc6ISO4Table) 47 | case FINGERPRINT: 48 | h = NewFingerprint() 49 | case NONE: 50 | h = NewNoneHash() 51 | default: 52 | panic(me) 53 | } 54 | return 55 | } 56 | 57 | //string hash with length 58 | func (me HashMethod) StringHashL(s string) (h string) { 59 | _h := me.New() 60 | if n, err := _h.Write([]byte(s)); err == nil { 61 | h = fmt.Sprintf("%010d-%x", n, _h.Sum(nil)) 62 | } 63 | return 64 | } 65 | 66 | //string hash 67 | func (me HashMethod) StringHash(s string) (h string) { 68 | _h := me.New() 69 | if _, err := _h.Write([]byte(s)); err == nil { 70 | h = fmt.Sprintf("%x", _h.Sum(nil)) 71 | } 72 | return 73 | } 74 | 75 | //func (me HashMethod) FileHash(path string) (h string, err error) { 76 | // return 77 | //} 78 | 79 | //create a hash object 80 | func New(t HashMethod) hash.Hash { 81 | return t.New() 82 | } 83 | -------------------------------------------------------------------------------- /hash/none_hash.go: -------------------------------------------------------------------------------- 1 | package hash 2 | 3 | import ( 4 | "bytes" 5 | "hash" 6 | "io" 7 | ) 8 | 9 | var ( 10 | gId uint32 11 | ) 12 | 13 | type NoneHash struct { 14 | id uint32 15 | } 16 | 17 | func NewNoneHash() hash.Hash { 18 | gId++ 19 | return &NoneHash{id: gId} 20 | } 21 | 22 | func (this *NoneHash) ReadFrom(r io.Reader) (n int64, err error) { 23 | return 24 | } 25 | 26 | func (this *NoneHash) Write(p []byte) (n int, err error) { 27 | return 28 | } 29 | 30 | func (this *NoneHash) Sum(b []byte) []byte { 31 | buf := bytes.NewBuffer(nil) 32 | id := this.id 33 | for i := uint(4); i > 0; i-- { 34 | buf.WriteByte(byte(id >> ((i - 1) * 8) & 0xff)) 35 | } 36 | return buf.Bytes() 37 | } 38 | 39 | func (this *NoneHash) Reset() { 40 | } 41 | 42 | func (this *NoneHash) Size() int { 43 | return 0 44 | } 45 | 46 | func (this *NoneHash) BlockSize() int { 47 | return 0 48 | } 49 | -------------------------------------------------------------------------------- /hash/robin.go: -------------------------------------------------------------------------------- 1 | package hash 2 | -------------------------------------------------------------------------------- /io/io.go: -------------------------------------------------------------------------------- 1 | //package io extends std.io 2 | package io 3 | 4 | import ( 5 | "io" 6 | ) 7 | 8 | //copy src to multi dsts 9 | func Copys(src io.Reader, dsts ...io.Writer) (written int64, err error) { 10 | return CopysBuffer(src, nil, dsts...) 11 | } 12 | 13 | //copy src to multi dsts 14 | func CopysBuffer(src io.Reader, buf []byte, dsts ...io.Writer) (written int64, err error) { 15 | if wt, ok := src.(io.WriterTo); ok { 16 | for _, dst := range dsts { 17 | if written, err = wt.WriteTo(dst); err != nil { 18 | break 19 | } 20 | } 21 | return 22 | } 23 | 24 | if buf == nil { 25 | buf = make([]byte, 32*1024) 26 | } 27 | ReadAll: 28 | for { 29 | nr, er := src.Read(buf) 30 | if nr > 0 { 31 | nw, ew := int(0), error(nil) 32 | for _, dst := range dsts { 33 | if nw, ew = dst.Write(buf[0:nr]); ew != nil { 34 | err = ew 35 | break ReadAll 36 | } 37 | } 38 | if nw > 0 { 39 | written += int64(nw) 40 | } 41 | if nr != nw { 42 | err = io.ErrShortWrite 43 | break 44 | } 45 | } 46 | 47 | if er != nil { 48 | if er != io.EOF { //ignore EOF 49 | err = er 50 | } 51 | break 52 | } 53 | } 54 | return 55 | } 56 | -------------------------------------------------------------------------------- /ipc/ipc.go: -------------------------------------------------------------------------------- 1 | package ipc 2 | -------------------------------------------------------------------------------- /lang/lang.go: -------------------------------------------------------------------------------- 1 | package lang 2 | -------------------------------------------------------------------------------- /log/agent.go: -------------------------------------------------------------------------------- 1 | package log 2 | -------------------------------------------------------------------------------- /log/client.go: -------------------------------------------------------------------------------- 1 | package log 2 | -------------------------------------------------------------------------------- /log/log.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | type LogType uint 4 | 5 | const ( 6 | LogTrace = iota 7 | LogConsole 8 | LogDebug 9 | LogLog 10 | LogWarn 11 | LogErr 12 | LogPanic 13 | LogUserBegin 14 | ) 15 | 16 | type LogOption uint 17 | 18 | const ( 19 | LogORemote LogOption = 1 << iota 20 | LogODb 21 | LogOCompress 22 | ) 23 | 24 | type Log struct { 25 | } 26 | -------------------------------------------------------------------------------- /log/server.go: -------------------------------------------------------------------------------- 1 | package log 2 | -------------------------------------------------------------------------------- /math/big_int.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | //big int 4 | type BigInt struct { 5 | d []uint32 6 | } 7 | 8 | //func (me BigInt) Add(o BigInt) BigInt {} 9 | //func (me BigInt) Sub(o BigInt) BigInt {} 10 | //func (me BigInt) Mul(o BigInt) BigInt {} 11 | //func (me BigInt) Div(o BigInt) BigInt {} 12 | //func (me BigInt) Power(o BigInt) BigInt {} 13 | -------------------------------------------------------------------------------- /math/bits_bytes.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func _check_bit(_idx uint32) bool { 8 | return _idx >= 0 && _idx < 32 9 | } 10 | func _check_byte(_idx uint32) bool { 11 | return _idx >= 0 && _idx < 4 12 | 13 | } 14 | func _check_word(_idx uint32) bool { 15 | return _idx >= 0 && _idx < 2 16 | } 17 | 18 | func GetBit(_val uint32, _idx uint32) (uint32, error) { 19 | if _check_bit(_idx) { 20 | r := (_val & (1 << _idx)) >> _idx 21 | return r, nil 22 | } 23 | return 0, fmt.Errorf("GetBit(%d,%d) bit index not in range", _val, _idx) 24 | } 25 | func GetByte(_val uint32, _idx uint32) (uint32, error) { 26 | if _check_byte(_idx) { 27 | bits := _idx * 8 28 | r := (_val & (0xFF << bits)) >> bits 29 | return r, nil 30 | } 31 | return 0, fmt.Errorf("GetByte(%d,%d) byte index not in range", _val, _idx) 32 | } 33 | func GetWord(_val uint32, _idx uint32) (uint32, error) { 34 | if _check_word(_idx) { 35 | bits := _idx * 16 36 | r := (_val & (0xFFFF << bits)) >> bits 37 | return r, nil 38 | } 39 | return 0, fmt.Errorf("GetWord(%d,%d) _word index not in range", _val, _idx) 40 | } 41 | -------------------------------------------------------------------------------- /math/bool.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | //bool 4 | type Bool bool 5 | 6 | func (me Bool) I() (i int) { 7 | if bool(me) { 8 | i = 1 9 | } 10 | return 11 | } 12 | 13 | func BToI(b Bool) int { 14 | return Bool(b).I() 15 | } 16 | func ItoB(i int) bool { 17 | return i != 0 18 | } 19 | -------------------------------------------------------------------------------- /math/cplx/complex.go: -------------------------------------------------------------------------------- 1 | package cplx 2 | 3 | type Cplx64 complex64 4 | 5 | func (this *Cplx64) Real() float32 { 6 | return real(*this) 7 | } 8 | func (this *Cplx64) Imag() float32 { 9 | return imag(*this) 10 | } 11 | 12 | type Cplx128 complex128 13 | 14 | func (this *Cplx128) Real() float64 { 15 | return real(*this) 16 | } 17 | func (this *Cplx128) Imag() float64 { 18 | return imag(*this) 19 | } 20 | -------------------------------------------------------------------------------- /math/float.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import ( 4 | "math" 5 | ) 6 | 7 | const ( 8 | Epslon = 0.000001 9 | ) 10 | 11 | func Equal(a, b float64) bool { return math.Abs(a-b) < Epslon } 12 | -------------------------------------------------------------------------------- /math/number/gp/number.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gxlb/gx/6e49935b2516acf71d09a401c66350e7699f154c/math/number/gp/number.gpg -------------------------------------------------------------------------------- /math/number/gp/rangenumber.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | 3 | //#GOGP_FILE_BEGIN 1 4 | 5 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 6 | //#GOGP_IGNORE_BEGIN //required from(github.com/vipally/gogp/lib/fakedef) 7 | //these defines are used to make sure this fake go file can be compiled correctlly 8 | //and they will be removed from real go files 9 | //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 10 | 11 | type GOGPValueType int // 12 | func (this GOGPValueType) Less(o GOGPValueType) bool { return this < o } 13 | func (this GOGPValueType) Show() string { return "" } // 14 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 15 | //#GOGP_IGNORE_END //required from(github.com/vipally/gogp/lib/fakedef) 16 | 17 | type rangeGOGPGlobalNamePrefix struct { 18 | min, max GOGPValueType 19 | } 20 | 21 | func (this *rangeGOGPGlobalNamePrefix) verify(val GOGPValueType) bool { 22 | return val >= this.min && val <= this.max 23 | } 24 | 25 | type GOGPGlobalNamePrefixRangeNumber struct { 26 | val GOGPValueType 27 | rng *rangeGOGPGlobalNamePrefix 28 | } 29 | 30 | type GOGPGlobalNamePrefix GOGPValueType 31 | 32 | func (me GOGPGlobalNamePrefix) Get() GOGPValueType { return GOGPValueType(me) } 33 | func (this *GOGPGlobalNamePrefix) Set(val GOGPValueType) { *this = GOGPGlobalNamePrefix(val) } 34 | func (me GOGPGlobalNamePrefix) Verify(val GOGPValueType) bool { 35 | return val >= GOGPGlobalNamePrefixMin && val <= GOGPGlobalNamePrefixMax 36 | } 37 | 38 | //#GOGP_FILE_END 39 | -------------------------------------------------------------------------------- /math/prime/prime.go: -------------------------------------------------------------------------------- 1 | package prime 2 | 3 | func IsPrime(num uint32) bool { 4 | if num < 2 { 5 | return false 6 | } 7 | if num == 2 || num == 3 { 8 | return true 9 | } 10 | mod := num % 6 11 | if mod != 1 && mod != 5 { 12 | return false 13 | } 14 | max := uint32(0) //uint64(math.Floor(math.Sqrt(float64(num)))) 15 | for i := 2; i < len(g_primes); i++ { 16 | prime := g_primes[i] 17 | if prime > max { 18 | break 19 | } 20 | if num%prime == 0 { 21 | return false 22 | } 23 | } 24 | return true 25 | } 26 | 27 | func step(shift uint32, val, sqrtVal *uint32) { 28 | magic := uint32(0x40000000) >> shift 29 | if (magic + *sqrtVal) <= *val { 30 | *val -= magic + *sqrtVal 31 | *sqrtVal = (*sqrtVal >> 1) | magic 32 | } else { 33 | *sqrtVal = *sqrtVal >> 1 34 | } 35 | } 36 | 37 | //a fast way to calculate sqrt 38 | func SqrtUint32(val uint32) uint32 { 39 | var sqrtVal uint32 = 0 40 | for i := uint32(0); i <= 30; i += 2 { 41 | step(i, &val, &sqrtVal) 42 | } 43 | if sqrtVal < val { 44 | sqrtVal++ 45 | } 46 | //sqrtVal <<= (Q_FACTOR) / 2 47 | 48 | return sqrtVal 49 | } 50 | -------------------------------------------------------------------------------- /math/rand/rand.go: -------------------------------------------------------------------------------- 1 | //Package rand implements some useful rand object 2 | package rand 3 | 4 | import ( 5 | "time" 6 | 7 | xtime "github.com/vipally/gx/time" 8 | ) 9 | 10 | //generate a seed for rand 11 | func RandSeed(init uint64) uint64 { 12 | r := xtime.RDTSC() + uint64(time.Now().Unix()) + init 13 | r = r*4294967291 + 8615693 14 | return r 15 | } 16 | -------------------------------------------------------------------------------- /math/rand/rand.gp: -------------------------------------------------------------------------------- 1 | //Package rand implements some useful rand object 2 | package rand 3 | 4 | import ( 5 | "sync/atomic" 6 | ) 7 | 8 | var ( 9 | gRand = NewRandS((RandSeed(0))) 10 | ) 11 | 12 | //generate a rand number 13 | func Rand() { 14 | return gRand.Rand() 15 | } 16 | 17 | //generate a rand number less than max 18 | func RandMax(max ) { 19 | return gRand.RandMax(max) 20 | } 21 | func RandRange(min, max ) { 22 | return gRand.RandRange(min, max) 23 | } 24 | 25 | //rand number generator 26 | //It is thread safe 27 | type RandT struct { 28 | seed 29 | //lock sync.Mutex 30 | } 31 | 32 | //new a initialized rand object 33 | func NewRandS(seed ) *RandT { 34 | return &RandT{seed: seed} 35 | } 36 | 37 | //new a rand object initialized by auto-generated seed 38 | func NewRand() *RandT { 39 | return NewRandS(gRand.randBase()) 40 | } 41 | 42 | //next rand number 43 | func (me *RandT) Rand() { 44 | var o, n 45 | for { //mutithread lock-free operation 46 | o = atomic.LoadUint(&me.seed) 47 | n = o* + 48 | if atomic.CompareAndSwapUint(&me.seed, o, n) { 49 | break 50 | } 51 | } 52 | return n 53 | 54 | //me.seed = me.seed*g_prime_a + g_prime_c 55 | //return me.seed 56 | } 57 | 58 | //new rand seed list 59 | func (me *RandT) randBase() { 60 | return (RandSeed(uint64(me.Rand()))) 61 | } 62 | 63 | //generate rand number in range 64 | func (me *RandT) RandRange(min, max ) { 65 | if max < min { 66 | max, min = min, max 67 | } 68 | d := max - min + 1 69 | r := me.Rand() 70 | ret := r%d + min 71 | 72 | return ret 73 | } 74 | 75 | //generate rand number with max value 76 | func (me *RandT) RandMax(max ) { 77 | return me.RandRange(0, max-1) 78 | } 79 | 80 | //get seed 81 | func (me *RandT) Seed() { 82 | return atomic.LoadUint(&me.seed) 83 | } 84 | 85 | //set seed 86 | func (me *RandT) Srand(_seed ) { 87 | ret := atomic.SwapUint(&me.seed, _seed) //mutithread lock-free operation 88 | return ret 89 | } 90 | -------------------------------------------------------------------------------- /math/rand/rand.gp_32.go: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // 3 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 4 | // 5 | // This file was auto-generated by tool [github.com/vipally/gogp] 6 | // Last update at: [Sun Oct 30 2016 18:40:52] 7 | // Generate from: 8 | // [github.com/vipally/gx/math/rand/rand.gp] 9 | // [github.com/vipally/gx/math/rand/rand.gpg] [32] 10 | // 11 | // Tool [github.com/vipally/gogp] info: 12 | // CopyRight 2016 @Ally Dale. All rights reserved. 13 | // Author : Ally Dale(vipally@gmail.com) 14 | // Blog : http://blog.csdn.net/vipally 15 | // Site : https://github.com/vipally 16 | // BuildAt : [Oct 24 2016 20:25:45] 17 | // Version : 3.0.0.final 18 | // 19 | /////////////////////////////////////////////////////////////////// 20 | 21 | //Package rand implements some useful rand object 22 | package rand 23 | 24 | import ( 25 | "sync/atomic" 26 | ) 27 | 28 | var ( 29 | gRand32 = NewRand32S(uint32(RandSeed(0))) 30 | ) 31 | 32 | //generate a rand number 33 | func Rand32() uint32 { 34 | return gRand32.Rand() 35 | } 36 | 37 | //generate a rand number less than max 38 | func RandMax32(max uint32) uint32 { 39 | return gRand32.RandMax(max) 40 | } 41 | func RandRange32(min, max uint32) uint32 { 42 | return gRand32.RandRange(min, max) 43 | } 44 | 45 | //rand number generator 46 | //It is thread safe 47 | type Rand32T struct { 48 | seed uint32 49 | //lock sync.Mutex 50 | } 51 | 52 | //new a initialized rand32 object 53 | func NewRand32S(seed uint32) *Rand32T { 54 | return &Rand32T{seed: seed} 55 | } 56 | 57 | //new a rand32 object initialized by auto-generated seed 58 | func NewRand32() *Rand32T { 59 | return NewRand32S(gRand32.randBase()) 60 | } 61 | 62 | //next rand number 63 | func (me *Rand32T) Rand() uint32 { 64 | var o, n uint32 65 | for { //mutithread lock-free operation 66 | o = atomic.LoadUint32(&me.seed) 67 | n = o*7368787 + 2750159 68 | if atomic.CompareAndSwapUint32(&me.seed, o, n) { 69 | break 70 | } 71 | } 72 | return n 73 | 74 | //me.seed = me.seed*g_prime_a32 + g_prime_c32 75 | //return me.seed 76 | } 77 | 78 | //new rand seed list 79 | func (me *Rand32T) randBase() uint32 { 80 | return uint32(RandSeed(uint64(me.Rand()))) 81 | } 82 | 83 | //generate rand number in range 84 | func (me *Rand32T) RandRange(min, max uint32) uint32 { 85 | if max < min { 86 | max, min = min, max 87 | } 88 | d := max - min + 1 89 | r := me.Rand() 90 | ret := r%d + min 91 | 92 | return ret 93 | } 94 | 95 | //generate rand number with max value 96 | func (me *Rand32T) RandMax(max uint32) uint32 { 97 | return me.RandRange(0, max-1) 98 | } 99 | 100 | //get seed 101 | func (me *Rand32T) Seed() uint32 { 102 | return atomic.LoadUint32(&me.seed) 103 | } 104 | 105 | //set seed 106 | func (me *Rand32T) Srand(_seed uint32) uint32 { 107 | ret := atomic.SwapUint32(&me.seed, _seed) //mutithread lock-free operation 108 | return ret 109 | } 110 | -------------------------------------------------------------------------------- /math/rand/rand.gp_64.go: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // 3 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 4 | // 5 | // This file was auto-generated by tool [github.com/vipally/gogp] 6 | // Last update at: [Sun Oct 30 2016 18:40:52] 7 | // Generate from: 8 | // [github.com/vipally/gx/math/rand/rand.gp] 9 | // [github.com/vipally/gx/math/rand/rand.gpg] [64] 10 | // 11 | // Tool [github.com/vipally/gogp] info: 12 | // CopyRight 2016 @Ally Dale. All rights reserved. 13 | // Author : Ally Dale(vipally@gmail.com) 14 | // Blog : http://blog.csdn.net/vipally 15 | // Site : https://github.com/vipally 16 | // BuildAt : [Oct 24 2016 20:25:45] 17 | // Version : 3.0.0.final 18 | // 19 | /////////////////////////////////////////////////////////////////// 20 | 21 | //Package rand implements some useful rand object 22 | package rand 23 | 24 | import ( 25 | "sync/atomic" 26 | ) 27 | 28 | var ( 29 | gRand64 = NewRand64S(uint64(RandSeed(0))) 30 | ) 31 | 32 | //generate a rand number 33 | func Rand64() uint64 { 34 | return gRand64.Rand() 35 | } 36 | 37 | //generate a rand number less than max 38 | func RandMax64(max uint64) uint64 { 39 | return gRand64.RandMax(max) 40 | } 41 | func RandRange64(min, max uint64) uint64 { 42 | return gRand64.RandRange(min, max) 43 | } 44 | 45 | //rand number generator 46 | //It is thread safe 47 | type Rand64T struct { 48 | seed uint64 49 | //lock sync.Mutex 50 | } 51 | 52 | //new a initialized rand64 object 53 | func NewRand64S(seed uint64) *Rand64T { 54 | return &Rand64T{seed: seed} 55 | } 56 | 57 | //new a rand64 object initialized by auto-generated seed 58 | func NewRand64() *Rand64T { 59 | return NewRand64S(gRand64.randBase()) 60 | } 61 | 62 | //next rand number 63 | func (me *Rand64T) Rand() uint64 { 64 | var o, n uint64 65 | for { //mutithread lock-free operation 66 | o = atomic.LoadUint64(&me.seed) 67 | n = o*4294955897 + 4094975977 68 | if atomic.CompareAndSwapUint64(&me.seed, o, n) { 69 | break 70 | } 71 | } 72 | return n 73 | 74 | //me.seed = me.seed*g_prime_a64 + g_prime_c64 75 | //return me.seed 76 | } 77 | 78 | //new rand seed list 79 | func (me *Rand64T) randBase() uint64 { 80 | return uint64(RandSeed(uint64(me.Rand()))) 81 | } 82 | 83 | //generate rand number in range 84 | func (me *Rand64T) RandRange(min, max uint64) uint64 { 85 | if max < min { 86 | max, min = min, max 87 | } 88 | d := max - min + 1 89 | r := me.Rand() 90 | ret := r%d + min 91 | 92 | return ret 93 | } 94 | 95 | //generate rand number with max value 96 | func (me *Rand64T) RandMax(max uint64) uint64 { 97 | return me.RandRange(0, max-1) 98 | } 99 | 100 | //get seed 101 | func (me *Rand64T) Seed() uint64 { 102 | return atomic.LoadUint64(&me.seed) 103 | } 104 | 105 | //set seed 106 | func (me *Rand64T) Srand(_seed uint64) uint64 { 107 | ret := atomic.SwapUint64(&me.seed, _seed) //mutithread lock-free operation 108 | return ret 109 | } 110 | -------------------------------------------------------------------------------- /math/rand/rand.gpg: -------------------------------------------------------------------------------- 1 | [32] 2 | GOGP_Ignore=true 3 | GOGP_GpFilePath=rand 4 | PRIME_A=7368787 5 | PRIME_C=2750159 6 | SEED_TYPE=uint32 7 | BITS=32 8 | 9 | [64] 10 | GOGP_Ignore=true 11 | GOGP_GpFilePath=rand 12 | PRIME_A=4294955897 13 | PRIME_C=4094975977 14 | SEED_TYPE=uint64 15 | BITS=64 -------------------------------------------------------------------------------- /math/rand/rand_test.go: -------------------------------------------------------------------------------- 1 | package rand 2 | 3 | import ( 4 | // "os" 5 | // "testing" 6 | 7 | _ "github.com/vipally/gogp" //auto run gogp tool at current path in test process 8 | ) 9 | 10 | //func TestCallGogp(t *testing.T) { 11 | // if dir, err := os.Getwd(); err == nil { 12 | // gogp.Work(dir) 13 | // } else { 14 | // panic(err) 15 | // } 16 | //} 17 | -------------------------------------------------------------------------------- /math/range_int32.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | 4 | -------------------------------------------------------------------------------- /math/range_int64.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | -------------------------------------------------------------------------------- /math/range_uint32.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | //aerr "vipally.gmail.com/basic/errors" 7 | ) 8 | 9 | var ( 10 | //errid_ru32_full, _ = aerr.Reg("[RangeUint32] out of range") 11 | ) 12 | 13 | //ranged uint32 object 14 | type RangeUint32 struct { 15 | val, min, max uint32 16 | } 17 | 18 | func NewRangeUint32(_val, _min, _max uint32) (r *RangeUint32, err error) { 19 | if err = verifyRangeUint32(_val, _min, _max); err == nil { 20 | r = &RangeUint32{val: _val, min: _min, max: _max} 21 | } 22 | return 23 | } 24 | 25 | func (me *RangeUint32) Reset() bool { 26 | me.val = me.min 27 | return true 28 | } 29 | 30 | func (me *RangeUint32) ResetR() bool { 31 | me.val = me.max 32 | return true 33 | } 34 | 35 | func (me *RangeUint32) Init(_val, _min, _max uint32) (err error) { 36 | if err = verifyRangeUint32(_val, _min, _max); err == nil { 37 | me.val, me.min, me.max = _val, _min, _max 38 | } 39 | return 40 | } 41 | 42 | func (me *RangeUint32) Add(other uint32) (r uint32, err error) { 43 | if math.MaxUint32-other < me.val { 44 | //return me.min, aerr.Newf(errid_ru32_full, "Add(%d) will cause out of range :%s", other, me.Info()) 45 | } 46 | v := me.val + other 47 | r, err = v, me.verify(v) 48 | return 49 | } 50 | func (me *RangeUint32) Sub(other uint32) (r uint32, err error) { 51 | if me.val < other { 52 | //return me.min, aerr.Newf(errid_ru32_full, "Sub(%d) will cause out of range :%s", other, me.Info()) 53 | } 54 | v := me.val - other 55 | r, err = v, me.verify(v) 56 | return 57 | } 58 | 59 | func (me *RangeUint32) Mul(other uint32) (r uint32, err error) { 60 | if other > 0 && math.MaxUint32/other < me.val { 61 | //return me.min, aerr.Newf(errid_ru32_full, "Mul(%d) will cause out of range :%s", other, me.Info()) 62 | } 63 | v := me.val * other 64 | r, err = v, me.verify(v) 65 | return 66 | } 67 | func (me *RangeUint32) Div(other uint32) (r uint32, err error) { 68 | if 0 == other { 69 | //return me.min, aerr.Newf(errid_ru32_full, "Div(%d) error:%s", other, me.Info()) 70 | } 71 | v := me.val / other 72 | r, err = v, me.verify(v) 73 | return 74 | } 75 | func (me *RangeUint32) Mod(other uint32) (r uint32, err error) { 76 | if 0 == other { 77 | return me.min, fmt.Errorf("[RangeUint32] Mod(%d) error:%s", other, me.Info()) 78 | } 79 | v := me.val % other 80 | r, err = v, me.verify(v) 81 | return 82 | } 83 | func (me *RangeUint32) Inc() (r uint32, err error) { 84 | if math.MaxUint32 == me.val { 85 | //return me.min, aerr.Newf(errid_ru32_full, "Inc() will cause out of range :%s", me.Info()) 86 | } 87 | r, err = me.Set(me.val + 1) 88 | return 89 | } 90 | func (me *RangeUint32) Dec(other uint32) (r uint32, err error) { 91 | if 0 == me.val { 92 | //return me.min, aerr.Newf(errid_ru32_full, "Dec() will cause out of range :%s", me.Info()) 93 | } 94 | r, err = me.Set(me.val - 1) 95 | return 96 | } 97 | func (me *RangeUint32) Set(other uint32) (r uint32, err error) { 98 | r = me.val 99 | if err = me.verify(other); err == nil { 100 | me.val = other 101 | } 102 | return 103 | } 104 | func (me *RangeUint32) Get() (r_val, r_min, r_max uint32) { 105 | return me.val, me.min, me.max 106 | } 107 | func (me *RangeUint32) Val() uint32 { 108 | return me.val 109 | } 110 | func (me *RangeUint32) Min() uint32 { 111 | return me.min 112 | } 113 | func (me *RangeUint32) Max() uint32 { 114 | return me.max 115 | } 116 | func (me *RangeUint32) InRange(other uint32) (r bool) { 117 | r = (other >= me.min && other <= me.max) 118 | return 119 | } 120 | func (me *RangeUint32) InCurrentRange(other uint32) (r bool) { 121 | r = (other >= me.min && other <= me.val) 122 | return 123 | } 124 | 125 | func (me *RangeUint32) String() string { 126 | s := fmt.Sprintf("RangeUint32{val:%d min:%d max:%d}", 127 | me.val, me.min, me.max) 128 | return s 129 | } 130 | 131 | func (me *RangeUint32) Info() string { 132 | s := fmt.Sprintf("%#v", *me) 133 | return s 134 | } 135 | 136 | func (me *RangeUint32) verify(_val uint32) (err error) { 137 | if !me.InRange(_val) { 138 | //err = aerr.Newf(errid_ru32_full, "val(%d) out of range[%d,%d]", _val, me.min, me.max) 139 | } 140 | return 141 | } 142 | 143 | func verifyRangeUint32(_val, _min, _max uint32) (err error) { 144 | if _min > _max { 145 | //err = aerr.New(errid_min_max_error) 146 | } else if _val < _min || _val > _max { 147 | //err = aerr.Newf(errid_ru32_full, "val(%d) out of range[%d,%d]", _val, _min, _max) 148 | } 149 | return 150 | } 151 | -------------------------------------------------------------------------------- /math/range_uint64.go: -------------------------------------------------------------------------------- 1 | // Copyright @Ally 2014. All rights reserved. 2 | // license that can be found in the LICENSE file. 3 | // contact the author by Email: vipally@gmail.com 4 | // blog site: http://blog.sina.com.cn/ally2014 5 | 6 | package math 7 | 8 | import ( 9 | "fmt" 10 | "math" 11 | //aerr "vipally.gmail.com/basic/errors" 12 | ) 13 | 14 | var ( 15 | //errid_ru64_full, _ = aerr.Reg("[RangeUInt64] out of range") 16 | //errid_min_max_error, _ = aerr.Reg("[min > max error]") 17 | ) 18 | 19 | //ranged uint64 object 20 | type RangeUInt64 struct { 21 | val, min, max uint64 22 | } 23 | 24 | func NewRangeUInt64(_val, _min, _max uint64) (r *RangeUInt64, err error) { 25 | if err = verifyRangeUInt64(_val, _min, _max); err == nil { 26 | r = &RangeUInt64{val: _val, min: _min, max: _max} 27 | } 28 | return 29 | } 30 | 31 | func (me *RangeUInt64) Reset() bool { 32 | me.val = me.min 33 | return true 34 | } 35 | 36 | func (me *RangeUInt64) ResetR() bool { 37 | me.val = me.max 38 | return true 39 | } 40 | 41 | func (me *RangeUInt64) Init(_val, _min, _max uint64) (err error) { 42 | if err = verifyRangeUInt64(_val, _min, _max); err == nil { 43 | me.val, me.min, me.max = _val, _min, _max 44 | } 45 | return 46 | } 47 | 48 | func (me *RangeUInt64) Add(other uint64) (r uint64, err error) { 49 | if math.MaxUint64-other < me.val { 50 | //return me.min, aerr.Newf(errid_ru64_full, "Add(%d) will cause out of range :%s", other, me.Info()) 51 | } 52 | v := me.val + other 53 | r, err = v, me.verify(v) 54 | return 55 | } 56 | func (me *RangeUInt64) Sub(other uint64) (r uint64, err error) { 57 | if me.val < other { 58 | //return me.min, aerr.Newf(errid_ru64_full, "Sub(%d) will cause out of range :%s", other, me.Info()) 59 | } 60 | v := me.val - other 61 | r, err = v, me.verify(v) 62 | return 63 | } 64 | 65 | func (me *RangeUInt64) Mul(other uint64) (r uint64, err error) { 66 | if other > 0 && math.MaxUint64/other < me.val { 67 | //return me.min, aerr.Newf(errid_ru64_full, "Mul(%d) will cause out of range :%s", other, me.Info()) 68 | } 69 | v := me.val * other 70 | r, err = v, me.verify(v) 71 | return 72 | } 73 | func (me *RangeUInt64) Div(other uint64) (r uint64, err error) { 74 | if 0 == other { 75 | //return me.min, aerr.Newf(errid_ru64_full, "Div(%d) error:%s", other, me.Info()) 76 | } 77 | v := me.val / other 78 | r, err = v, me.verify(v) 79 | return 80 | } 81 | func (me *RangeUInt64) Mod(other uint64) (r uint64, err error) { 82 | if 0 == other { 83 | //return me.min, fmt.Errorf("[RangeUInt64] Mod(%d) error:%s", other, me.Info()) 84 | } 85 | v := me.val % other 86 | r, err = v, me.verify(v) 87 | return 88 | } 89 | func (me *RangeUInt64) Inc() (r uint64, err error) { 90 | if math.MaxUint64 == me.val { 91 | //return me.min, aerr.Newf(errid_ru64_full, "Inc() will cause out of range :%s", me.Info()) 92 | } 93 | r, err = me.Set(me.val + 1) 94 | return 95 | } 96 | func (me *RangeUInt64) Dec(other uint64) (r uint64, err error) { 97 | if 0 == me.val { 98 | //return me.min, aerr.Newf(errid_ru64_full, "Dec() will cause out of range :%s", me.Info()) 99 | } 100 | r, err = me.Set(me.val - 1) 101 | return 102 | } 103 | func (me *RangeUInt64) Set(other uint64) (r uint64, err error) { 104 | r = me.val 105 | if err = me.verify(other); err == nil { 106 | me.val = other 107 | } 108 | return 109 | } 110 | func (me *RangeUInt64) Get() (r_val, r_min, r_max uint64) { 111 | return me.val, me.min, me.max 112 | } 113 | func (me *RangeUInt64) Val() uint64 { 114 | return me.val 115 | } 116 | func (me *RangeUInt64) Min() uint64 { 117 | return me.min 118 | } 119 | func (me *RangeUInt64) Max() uint64 { 120 | return me.max 121 | } 122 | func (me *RangeUInt64) InRange(other uint64) (r bool) { 123 | r = (other >= me.min && other <= me.max) 124 | return 125 | } 126 | 127 | func (me *RangeUInt64) InCurrentRange(other uint64) (r bool) { 128 | r = (other >= me.min && other <= me.val) 129 | return 130 | } 131 | 132 | func (me *RangeUInt64) Info() string { 133 | s := fmt.Sprintf("%#v", *me) 134 | return s 135 | } 136 | 137 | func (me *RangeUInt64) verify(_val uint64) (err error) { 138 | if !me.InRange(_val) { 139 | //err = aerr.Newf(errid_ru64_full, "val(%d) out of range[%d,%d]", _val, me.min, me.max) 140 | } 141 | return 142 | } 143 | 144 | func verifyRangeUInt64(_val, _min, _max uint64) (err error) { 145 | if _min > _max { 146 | //err = aerr.New(errid_min_max_error) 147 | } else if _val < _min || _val > _max { 148 | //err = aerr.Newf(errid_ru64_full, "val(%d) out of range[%d,%d]", _val, _min, _max) 149 | } 150 | return 151 | } 152 | -------------------------------------------------------------------------------- /math/seq/sequence.go: -------------------------------------------------------------------------------- 1 | package seq 2 | 3 | import ( 4 | "math" 5 | ) 6 | 7 | type SeqOption uint32 8 | 9 | const ( 10 | MEM SeqOption = 1 //only in memory 11 | STORE SeqOption = 2 //with storage 12 | _storage_type_bits = 4 13 | _get_storage = (1 << _storage_type_bits) - 1 14 | 15 | NO_REC SeqOption = 1 << _storage_type_bits //never recycle any id 16 | REC_LOOP SeqOption = 2 << _storage_type_bits //gen id by loop 17 | REC_FST SeqOption = 3 << _storage_type_bits //use recycled-id first 18 | REC_LST SeqOption = 4 << _storage_type_bits //use unused-id first 19 | _recycle_type_bits = 4 20 | _get_cecycle = (1<<_recycle_type_bits - 1) << _storage_type_bits 21 | 22 | NOUSE_FST = 1 << (_storage_type_bits + _recycle_type_bits) 23 | PANIC_ERR = 2 << (_storage_type_bits + _recycle_type_bits) //panic with error 24 | _usage_option_bits = 4 25 | _get_usage_option = (1<<_usage_option_bits - 1) << (_storage_type_bits + _recycle_type_bits) 26 | 27 | DFT_OP_ID_INC = MEM | NO_REC | NOUSE_FST 28 | DFT_OP_ID_NO_ERR = MEM | NO_REC | NOUSE_FST | PANIC_ERR 29 | DFT_OP_ID_LOOP = MEM | REC_LOOP | NOUSE_FST 30 | DFT_OP_ID_RECF = MEM | REC_FST | NOUSE_FST 31 | DFT_OP_ID_RECL = MEM | REC_LST | NOUSE_FST 32 | DFT_OP_ID_GBL = STORE | NO_REC | REC_FST | NOUSE_FST 33 | 34 | MAX_SEQ64 = math.MaxUint64 35 | MAX_SEQ32 = math.MaxUint32 36 | ) 37 | -------------------------------------------------------------------------------- /math/seq/sequence32.go: -------------------------------------------------------------------------------- 1 | package seq 2 | 3 | -------------------------------------------------------------------------------- /math/seq/sequence64.go: -------------------------------------------------------------------------------- 1 | //Package seq implements some useful sequence generating objects 2 | package seq 3 | 4 | import ( 5 | "fmt" 6 | aerr "vipally.gmail.com/basic/errors" 7 | amath "vipally.gmail.com/basic/math" 8 | async "vipally.gmail.com/basic/sync" 9 | ) 10 | 11 | var ( 12 | errid_Seq64_err, _ = aerr.Reg("Seq64 error") 13 | ) 14 | 15 | func SeqNext64(seq *async.AutoLock) (r uint64) { 16 | s := seq.LockGet().(*Seq64) 17 | defer seq.Unlock() 18 | r, _ = s.Next() 19 | return 20 | } 21 | 22 | type Seq64 struct { 23 | id amath.RangeUInt64 24 | id_name string 25 | id_option SeqOption 26 | } 27 | 28 | func NewSeq64(_min, _max uint64, 29 | _name string, _option SeqOption) *Seq64 { 30 | p := &Seq64{ 31 | id_name: _name, 32 | id_option: _option} 33 | err := p.id.Init(_min, _min, _max) 34 | if nil != err { 35 | //need log 36 | return nil 37 | } 38 | p.id.Reset() 39 | if (_option & _get_usage_option) == NOUSE_FST { 40 | p.id.Inc() 41 | } 42 | return p 43 | } 44 | 45 | func (me *Seq64) Current() (r uint64) { 46 | r, _, _ = me.id.Get() 47 | return 48 | } 49 | func (me *Seq64) Min() (r uint64) { 50 | return me.id.Min() 51 | } 52 | func (me *Seq64) Max() (r uint64) { 53 | return me.id.Max() 54 | } 55 | func (me *Seq64) Next() (r uint64, err error) { 56 | defer func() { //error handler 57 | if err != nil && me.id_option&PANIC_ERR == PANIC_ERR { 58 | panic(err) 59 | } 60 | }() 61 | 62 | if r, err = me.pop_recycle(REC_FST); err != nil { //use recycled first 63 | return 64 | } 65 | 66 | r, err = me.id.Inc() 67 | if err != nil { 68 | if me.id_option&_get_cecycle == NO_REC { 69 | s := fmt.Sprintf("Seq used up:%#v", *me) 70 | panic(s) 71 | } 72 | if r, err = me.pop_recycle(REC_LST); err != nil { 73 | return 74 | } 75 | } 76 | 77 | return 78 | } 79 | 80 | func (me *Seq64) NextNoErr() (r uint64) { 81 | var err error 82 | if r, err = me.Next(); err != nil { 83 | //log 84 | fmt.Println(err) 85 | } 86 | return 87 | } 88 | 89 | func (me *Seq64) Recycle(r uint64) (err error) { 90 | if me.id.InCurrentRange(r) { 91 | err = me.push_recycle(r) 92 | } else { 93 | err = aerr.Newf(errid_Seq64_err, "Recycle(%d) not range : %s", r, me.Infor()) 94 | } 95 | return 96 | } 97 | 98 | func (me *Seq64) Infor() string { 99 | s := fmt.Sprintf("%#v", *me) 100 | return s 101 | } 102 | 103 | //recycled id manager 104 | //storage depend 105 | func (me *Seq64) push_recycle(r uint64) (err error) { 106 | return 107 | } 108 | func (me *Seq64) pop_recycle(_recycle_type SeqOption) (r uint64, err error) { 109 | if (me.id_option & _get_cecycle) == _recycle_type { 110 | 111 | } 112 | return 113 | } 114 | -------------------------------------------------------------------------------- /math/uint64.go: -------------------------------------------------------------------------------- 1 | package math 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Uint64 uint64 8 | 9 | func (me Uint64) CommaString() string { 10 | r := Uint64(1000) 11 | l := me 12 | s := "" 13 | for l >= r { 14 | d := l % r 15 | l /= r 16 | s = fmt.Sprintf(",%03d%s", d, s) 17 | } 18 | s = fmt.Sprintf("%d%s", l, s) 19 | return s 20 | } 21 | -------------------------------------------------------------------------------- /net/net.go: -------------------------------------------------------------------------------- 1 | package net 2 | -------------------------------------------------------------------------------- /os/os.go: -------------------------------------------------------------------------------- 1 | package os 2 | -------------------------------------------------------------------------------- /pool/buffer.go: -------------------------------------------------------------------------------- 1 | package pool 2 | -------------------------------------------------------------------------------- /pool/logi/pool.go: -------------------------------------------------------------------------------- 1 | package logi 2 | 3 | //manage a large block 4 | type Page struct { 5 | //[]block 6 | } 7 | 8 | type Block struct { 9 | } 10 | 11 | //manage fix-size blocks 12 | type FixPool struct { 13 | //page-set 14 | //page-map 15 | //free-list 16 | } 17 | type LogiPool struct { 18 | //[]FixPool 19 | //max_free_list_len 20 | //max_bytes 21 | } 22 | -------------------------------------------------------------------------------- /proto/any.go: -------------------------------------------------------------------------------- 1 | package proto 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | var ( 8 | gTypeMap map[string]*reflect.Type 9 | 10 | //typeID? 11 | ) 12 | 13 | type TypeId uint 14 | 15 | //func (me TypeId) New() Any {} 16 | //func (me TypeId) Load(b []byte) Any {} 17 | 18 | //func NewTypeRegister() 19 | 20 | //register a type, return it's unique id 21 | //this TypeId can use to create new values of this type 22 | func RegType(name string, i interface{}) TypeId { //TypeId=hash(name)? 23 | return 0 24 | } 25 | 26 | type Kind reflect.Kind 27 | 28 | const ( 29 | Invalid = Kind(reflect.Invalid) //0 30 | Bool = Kind(reflect.Bool) //1 31 | Int = Kind(reflect.Int) //2 32 | Int8 = Kind(reflect.Int8) //3 33 | Int16 = Kind(reflect.Int16) //4 34 | Int32 = Kind(reflect.Int32) //5 35 | Int64 = Kind(reflect.Int64) //6 36 | Uint = Kind(reflect.Uint) //7 37 | Uint8 = Kind(reflect.Uint8) //8 38 | Uint16 = Kind(reflect.Uint16) //9 39 | Uint32 = Kind(reflect.Uint32) //10 40 | Uint64 = Kind(reflect.Uint64) //11 41 | Float32 = Kind(reflect.Float32) //13 42 | Float64 = Kind(reflect.Float64) //14 43 | Complex64 = Kind(reflect.Complex64) //15 44 | Complex128 = Kind(reflect.Complex128) //16 45 | 46 | Array = Kind(reflect.Array) //17 47 | Map = Kind(reflect.Map) //21 48 | Slice = Kind(reflect.Slice) //23 49 | String = Kind(reflect.String) //24 50 | Struct = Kind(reflect.Struct) //25 51 | 52 | //these kind will not support Pack/Unpack 53 | Uintptr = Kind(reflect.Uintptr) //12 54 | Chan = Kind(reflect.Chan) //18 55 | Func = Kind(reflect.Func) //19 56 | Interface = Kind(reflect.Interface) //20 57 | Ptr = Kind(reflect.Ptr) //22 58 | UnsafePointer = Kind(reflect.UnsafePointer) //26 59 | ) 60 | 61 | func Unpack([]byte) (any Any) { 62 | return 63 | } 64 | 65 | type Any interface { 66 | String() string 67 | FromString(string) 68 | Kind() Kind 69 | Pack(b []byte) []byte 70 | Unpack([]byte) Any 71 | } 72 | 73 | type IntValue int 74 | type StringValue string 75 | type BoolValue bool 76 | type StructValue struct { 77 | fieldsMap map[string]int 78 | fields []Any 79 | v reflect.Value 80 | } 81 | -------------------------------------------------------------------------------- /proto/int.go: -------------------------------------------------------------------------------- 1 | package proto 2 | 3 | //#GOGP_IGNORE_BEGIN//////////////////////////////GOGPCommentDummyGoFile_BEGIN 4 | // 5 | // 6 | ///* //<----This line can be uncommented to disable all this file, and it doesn't effect to the .gp file 7 | // //If test or change .gp file required, comment it to modify and cmomile as normal go file 8 | // 9 | // 10 | // This is exactly not a real go code file 11 | // It is used to generate .gp file by gogp tool 12 | // Real go code file will be generated from .gp file 13 | // 14 | //#GOGP_IGNORE_END////////////////////////////////GOGPCommentDummyGoFile 15 | 16 | // 17 | // 18 | // 19 | //add import here.......... 20 | // 21 | // 22 | // 23 | 24 | //#GOGP_IGNORE_BEGIN//////////////////////////////GOGPDummyDefine 25 | // 26 | //these defines is used to make sure this dummy go file can be compiled correctlly 27 | //and they will be removed from real go files 28 | //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 29 | // 30 | //add dummy defines here.......... 31 | // 32 | // 33 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 34 | //#GOGP_IGNORE_END////////////////////////////////GOGPDummyDefine 35 | 36 | // 37 | // 38 | //add file body here.......... 39 | // 40 | // 41 | 42 | //#GOGP_IGNORE_BEGIN//////////////////////////////GOGPCommentDummyGoFile 43 | //*/ 44 | //#GOGP_IGNORE_END////////////////////////////////GOGPCommentDummyGoFile_END 45 | -------------------------------------------------------------------------------- /proto/integer.go: -------------------------------------------------------------------------------- 1 | package proto 2 | 3 | type Integer int64 4 | type UInteger uint64 5 | 6 | func (me Integer) Int64() int64 { 7 | return int64(me) 8 | } 9 | 10 | func (me Integer) Int32() int64 { 11 | return int32(me) 12 | } 13 | 14 | func (me Integer) Int16() int64 { 15 | return int16(me) 16 | } 17 | 18 | func (me Integer) Int8() int64 { 19 | return int8(me) 20 | } 21 | 22 | func (me UInteger) Uint64() int64 { 23 | return int64(me) 24 | } 25 | 26 | func (me Uinteger) Uint32() int64 { 27 | return int32(me) 28 | } 29 | 30 | func (me Uinteger) Uint16() int64 { 31 | return int16(me) 32 | } 33 | 34 | func (me Uinteger) Uint8() int64 { 35 | return int8(me) 36 | } 37 | -------------------------------------------------------------------------------- /proto/protocol.go: -------------------------------------------------------------------------------- 1 | package proto 2 | -------------------------------------------------------------------------------- /reflect/reflect.go: -------------------------------------------------------------------------------- 1 | package reflect 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | //new object same the type as sample 8 | func New(sample interface{}) interface{} { 9 | t := reflect.TypeOf(sample) 10 | v := reflect.New(t).Interface() 11 | return v 12 | } 13 | 14 | //check if the same type 15 | func IsSameType(l, r interface{}) (ok bool) { 16 | tl, tr := reflect.TypeOf(l), reflect.TypeOf(r) 17 | return tl == tr 18 | } 19 | 20 | //get kind 21 | func Kind(l interface{}) reflect.Kind { 22 | return reflect.TypeOf(l).Kind() 23 | } 24 | 25 | //check if cmpareable inner type 26 | func IsCmpableInnterType(t interface{}) bool { 27 | switch t.(type) { 28 | case int, uint, int8, uint8, int16, uint16, int32, uint32, int64, uint64, string, float32, float64: 29 | return true 30 | } 31 | return false 32 | } 33 | -------------------------------------------------------------------------------- /reflect/reflect_test.go: -------------------------------------------------------------------------------- 1 | package reflect_test 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "testing" 7 | //"time" 8 | 9 | xreflect "github.com/vipally/gx/reflect" 10 | ) 11 | 12 | type I int 13 | 14 | func TestNew(t *testing.T) { 15 | f := 1 16 | n := xreflect.New(f) 17 | fmt.Println(&f, n, reflect.ValueOf(n)) 18 | var ( 19 | i I = 1 20 | j I = 2 21 | b byte = 1 22 | u8 rune = 2 23 | ) 24 | fmt.Println(i + j) 25 | fmt.Println(reflect.TypeOf(i).PkgPath()) 26 | fmt.Println(xreflect.IsSameType(b, u8)) 27 | //fmt.Println(xreflect.IsCmpableInnterType(f)) 28 | fmt.Println(xreflect.IsSameType(uint8(0), byte(0))) 29 | fmt.Println(xreflect.IsSameType(rune(0), int32(0))) 30 | } 31 | 32 | func Benchmark_TypeCheck(b *testing.B) { 33 | b.N = 2100000000 34 | for ii := 0; ii < 100000000; ii++ { 35 | f := 1 36 | var i I = 1 37 | xreflect.IsSameType(f, i) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /regable/doc.go: -------------------------------------------------------------------------------- 1 | //Assuming that all of the acts are registered in the initialization phase 2 | //So do not use locks on regers 3 | package regable 4 | -------------------------------------------------------------------------------- /regable/gp/factory.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | 3 | //#GOGP_FILE_BEGIN 4 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 5 | type Product interface{} 6 | type GOGPParaType int 7 | type GOGPIdType uint32 8 | 9 | type Creater interface { 10 | Create(GOGPPara GOGPParaType) Product 11 | Name() string 12 | Id() GOGPIdType 13 | } 14 | 15 | type GOGPGlobalNamePrefixFactory struct { 16 | lock bool //if the factory is lock for regist 17 | } 18 | 19 | func (this *GOGPGlobalNamePrefixFactory) RegCreater(creater Creater) error { 20 | return nil 21 | } 22 | 23 | func (this *GOGPGlobalNamePrefixFactory) Lock() { 24 | this.lock = true 25 | } 26 | 27 | func (this *GOGPGlobalNamePrefixFactory) GetCreaterById(id GOGPIdType) (creater Creater, ok bool) { 28 | return 29 | } 30 | 31 | func (this *GOGPGlobalNamePrefixFactory) GetCreaterByName(name string) (creater Creater, ok bool) { 32 | return 33 | } 34 | 35 | func (this *GOGPGlobalNamePrefixFactory) CreateById(id GOGPIdType, GOGPPara GOGPParaType) (product Product, ok bool) { 36 | return 37 | } 38 | 39 | func (this *GOGPGlobalNamePrefixFactory) CreateByName(name string, GOGPPara GOGPParaType) (product Product, ok bool) { 40 | return 41 | } 42 | 43 | //#GOGP_FILE_END 44 | -------------------------------------------------------------------------------- /regable/gp/gp.gpg: -------------------------------------------------------------------------------- 1 | [GOGP_REVERSE_mapping] 2 | GOGP_GpFilePath=github.com/vipally/gx/regable/gp/mapping 3 | PACKAGE=package gp 4 | KEY_TYPE=GOGPKeyType 5 | VALUE_TYPE=GOGPValueType 6 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix -------------------------------------------------------------------------------- /regable/gp/mapping.gp: -------------------------------------------------------------------------------- 1 | //#GOGP_IGNORE_BEGIN 2 | /////////////////////////////////////////////////////////////////// 3 | // 4 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 5 | // 6 | // This file was auto-generated by tool [github.com/vipally/gogp] 7 | // Last update at: [Sat Apr 01 2017 22:48:08] 8 | // Generate from: 9 | // [github.com/vipally/gx/regable/gp/mapping.gp.go] 10 | // [github.com/vipally/gx/regable/gp/gp.gpg] [GOGP_REVERSE_mapping] 11 | // 12 | // Tool [github.com/vipally/gogp] info: 13 | // CopyRight 2016 @Ally Dale. All rights reserved. 14 | // Author : Ally Dale(vipally@gmail.com) 15 | // Blog : http://blog.csdn.net/vipally 16 | // Site : https://github.com/vipally 17 | // BuildAt : 18 | // Version : 3.0.0.final 19 | // 20 | /////////////////////////////////////////////////////////////////// 21 | //#GOGP_IGNORE_END 22 | 23 | 24 | 25 | import ( 26 | "fmt" 27 | ) 28 | 29 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 30 | 31 | //key/value mapping 32 | type Mapping struct { 33 | normal map[] 34 | reverse map[] 35 | } 36 | 37 | type MappingIdType 38 | 39 | func NewMapping() *Mapping { 40 | p := &Mapping{} 41 | p.Init() 42 | return p 43 | } 44 | 45 | func (this *Mapping) Init() { 46 | this.normal = make(map[]) 47 | this.reverse = make(map[]) 48 | } 49 | 50 | //make mapping 51 | func (this *Mapping) Insert(k , v ) (id MappingIdType, err error) { 52 | if _, ok := this.Find(k); ok { 53 | err = fmt.Errorf("dumplicate key : %#v", k) 54 | return 55 | } 56 | if _, ok := this.ReverseFind(v); ok { 57 | err = fmt.Errorf("dumplicate value : %#v", v) 58 | return 59 | } 60 | this.normal[k] = v 61 | this.reverse[v] = k 62 | return MappingIdType(k), nil 63 | } 64 | 65 | //remove by key 66 | func (this *Mapping) RemoveByKey(k ) (ok bool) { 67 | if v, find := this.Find(k); find { 68 | ok = find 69 | delete(this.normal, k) 70 | delete(this.reverse, v) 71 | } 72 | return 73 | } 74 | 75 | //remove by value 76 | func (this *Mapping) RemoveByValue(v ) (ok bool) { 77 | if k, find := this.ReverseFind(v); find { 78 | ok = find 79 | delete(this.normal, k) 80 | delete(this.reverse, v) 81 | } 82 | return 83 | } 84 | 85 | //find by key 86 | func (this *Mapping) Find(k ) (v , ok bool) { 87 | v, ok = this.normal[k] 88 | return 89 | } 90 | 91 | //find by value 92 | func (this *Mapping) ReverseFind(v ) (k , ok bool) { 93 | k, ok = this.reverse[v] 94 | return 95 | } 96 | 97 | //clear all mapping 98 | func (this *Mapping) Clear() { 99 | this.Init() 100 | } 101 | 102 | -------------------------------------------------------------------------------- /regable/gp/mapping.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | 3 | //#GOGP_FILE_BEGIN 4 | //#GOGP_IGNORE_BEGIN ///gogp_file_begin 5 | // 6 | /* //This line can be uncommented to disable all this file, and it doesn't effect to the .gp file 7 | // //If test or change .gp file required, comment it to modify and cmomile as normal go file 8 | // 9 | // This is a fake go code file 10 | // It is used to generate .gp file by gogp tool 11 | // Real go code file will be generated from .gp file 12 | // 13 | //#GOGP_IGNORE_END ///gogp_file_begin 14 | 15 | import ( 16 | "fmt" 17 | ) 18 | 19 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 20 | //#GOGP_IGNORE_BEGIN ///require begin from(github.com/vipally/gogp/lib/fakedef) 21 | //these defines are used to make sure this fake go file can be compiled correctlly 22 | //and they will be removed from real go files 23 | //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 24 | 25 | type GOGPKeyType int // 26 | func (this GOGPKeyType) Less(o GOGPKeyType) bool { return this < o } 27 | func (this GOGPKeyType) Show() string { return "" } // 28 | 29 | type GOGPValueType int // 30 | func (this GOGPValueType) Less(o GOGPValueType) bool { return this < o } 31 | func (this GOGPValueType) Show() string { return "" } // 32 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 33 | //#GOGP_IGNORE_END ///require end from(github.com/vipally/gogp/lib/fakedef) 34 | 35 | //key/value mapping 36 | type GOGPGlobalNamePrefixMapping struct { 37 | normal map[GOGPKeyType]GOGPValueType 38 | reverse map[GOGPValueType]GOGPKeyType 39 | } 40 | 41 | type GOGPGlobalNamePrefixMappingIdType GOGPKeyType 42 | 43 | func NewGOGPGlobalNamePrefixMapping() *GOGPGlobalNamePrefixMapping { 44 | p := &GOGPGlobalNamePrefixMapping{} 45 | p.Init() 46 | return p 47 | } 48 | 49 | func (this *GOGPGlobalNamePrefixMapping) Init() { 50 | this.normal = make(map[GOGPKeyType]GOGPValueType) 51 | this.reverse = make(map[GOGPValueType]GOGPKeyType) 52 | } 53 | 54 | //make mapping 55 | func (this *GOGPGlobalNamePrefixMapping) Insert(k GOGPKeyType, v GOGPValueType) (id GOGPGlobalNamePrefixMappingIdType, err error) { 56 | if _, ok := this.Find(k); ok { 57 | err = fmt.Errorf("dumplicate key : %#v", k) 58 | return 59 | } 60 | if _, ok := this.ReverseFind(v); ok { 61 | err = fmt.Errorf("dumplicate value : %#v", v) 62 | return 63 | } 64 | this.normal[k] = v 65 | this.reverse[v] = k 66 | return GOGPGlobalNamePrefixMappingIdType(k), nil 67 | } 68 | 69 | //remove by key 70 | func (this *GOGPGlobalNamePrefixMapping) RemoveByKey(k GOGPKeyType) (ok bool) { 71 | if v, find := this.Find(k); find { 72 | ok = find 73 | delete(this.normal, k) 74 | delete(this.reverse, v) 75 | } 76 | return 77 | } 78 | 79 | //remove by value 80 | func (this *GOGPGlobalNamePrefixMapping) RemoveByValue(v GOGPValueType) (ok bool) { 81 | if k, find := this.ReverseFind(v); find { 82 | ok = find 83 | delete(this.normal, k) 84 | delete(this.reverse, v) 85 | } 86 | return 87 | } 88 | 89 | //find by key 90 | func (this *GOGPGlobalNamePrefixMapping) Find(k GOGPKeyType) (v GOGPValueType, ok bool) { 91 | v, ok = this.normal[k] 92 | return 93 | } 94 | 95 | //find by value 96 | func (this *GOGPGlobalNamePrefixMapping) ReverseFind(v GOGPValueType) (k GOGPKeyType, ok bool) { 97 | k, ok = this.reverse[v] 98 | return 99 | } 100 | 101 | //clear all mapping 102 | func (this *GOGPGlobalNamePrefixMapping) Clear() { 103 | this.Init() 104 | } 105 | 106 | //#GOGP_FILE_END 107 | //#GOGP_IGNORE_BEGIN ///gogp_file_end 108 | //*/ 109 | //#GOGP_IGNORE_END ///gogp_file_end 110 | -------------------------------------------------------------------------------- /regable/gp/regist.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | 3 | //#GOGP_FILE_BEGIN 4 | 5 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 6 | //type GOGPValueType int 7 | 8 | //func NewGOGPGlobalNamePrefixReger(name string) (*GOGPGlobalNamePrefixReger, error) { 9 | // return nil, nil 10 | //} 11 | 12 | //type GOGPGlobalNamePrefixReger struct { 13 | // regerId uint8 14 | // name string 15 | // subIdGen uint32 16 | // regList []*_GOGPGlobalNamePrefixRecord 17 | //} 18 | 19 | //type _GOGPGlobalNamePrefixRecord struct { 20 | // //name string 21 | // val GOGPValueType 22 | // id uint32 23 | //} 24 | 25 | //type GOGPGlobalNamePrefixRegerManager struct { 26 | // list []*GOGPGlobalNamePrefixReger 27 | //} 28 | 29 | //#GOGP_FILE_END 30 | -------------------------------------------------------------------------------- /regable/reg.gpg: -------------------------------------------------------------------------------- 1 | ;this is exactlly an ini file 2 | ;it wat used to generate code from .gp file 3 | [GOGP_IGNORE_bool] 4 | GOGP_GpFilePath=reg 5 | TYPENAME_L_SHORT=bool 6 | LOCK_COMMENT= 7 | REVERSE_COMMENT= 8 | NAME_INSTEAD= 9 | NAME_COMMENT_B= 10 | NAME_COMMENT_E= 11 | VALUE_TYPE=bool 12 | DEFAULT_REG_CNT=1024 13 | TYPENAME_L=bool 14 | TYPENAME_U=Bool 15 | 16 | [GOGP_IGNORE_uint32] 17 | GOGP_GpFilePath=reg 18 | TYPENAME_L_SHORT=u32 19 | LOCK_COMMENT= 20 | REVERSE_COMMENT=// 21 | NAME_INSTEAD= 22 | NAME_COMMENT_B= 23 | NAME_COMMENT_E= 24 | VALUE_TYPE=uint32 25 | DEFAULT_REG_CNT=1024 26 | TYPENAME_L=uint32 27 | TYPENAME_U=Uint32 28 | 29 | [GOGP_IGNORE_cu32] 30 | GOGP_GpFilePath=reg 31 | TYPENAME_L_SHORT=const_u32 32 | LOCK_COMMENT=// 33 | REVERSE_COMMENT=// 34 | NAME_INSTEAD= 35 | NAME_COMMENT_B= 36 | NAME_COMMENT_E= 37 | VALUE_TYPE=uint32 38 | DEFAULT_REG_CNT=1024 39 | TYPENAME_L=const_uint32 40 | TYPENAME_U=ConstUint32 41 | 42 | [GOGP_IGNORE_noname_cu32] 43 | GOGP_GpFilePath=reg 44 | TYPENAME_L_SHORT=noname_cu32 45 | LOCK_COMMENT=// 46 | REVERSE_COMMENT=// 47 | NAME_INSTEAD=g_no_name 48 | NAME_COMMENT_B=/* 49 | NAME_COMMENT_E=*/ 50 | VALUE_TYPE=uint32 51 | DEFAULT_REG_CNT=1024 52 | TYPENAME_L=noname_cu32 53 | TYPENAME_U=NoNameConstUint32 54 | 55 | [GOGP_IGNORE_str] 56 | GOGP_GpFilePath=reg 57 | TYPENAME_L_SHORT=str 58 | LOCK_COMMENT= 59 | REVERSE_COMMENT=// 60 | NAME_INSTEAD="" 61 | NAME_COMMENT_B=/* 62 | NAME_COMMENT_E=*/ 63 | VALUE_TYPE=string 64 | DEFAULT_REG_CNT=1024 65 | TYPENAME_L=string 66 | TYPENAME_U=String 67 | 68 | [GOGP_IGNORE_cstr] 69 | GOGP_GpFilePath=reg 70 | TYPENAME_L_SHORT=cstr 71 | LOCK_COMMENT=// 72 | REVERSE_COMMENT=// 73 | NAME_INSTEAD="" 74 | NAME_COMMENT_B=/* 75 | NAME_COMMENT_E=*/ 76 | VALUE_TYPE=string 77 | DEFAULT_REG_CNT=1024 78 | TYPENAME_L=const_str 79 | TYPENAME_U=ConstString 80 | 81 | [GOGP_IGNORE_iter] 82 | GOGP_GpFilePath=reg 83 | TYPENAME_L_SHORT=iter 84 | LOCK_COMMENT= 85 | REVERSE_COMMENT=// 86 | NAME_INSTEAD= 87 | NAME_COMMENT_B= 88 | NAME_COMMENT_E= 89 | VALUE_TYPE=interface{} 90 | DEFAULT_REG_CNT=1024 91 | TYPENAME_L=interface 92 | TYPENAME_U=Inerface 93 | 94 | [GOGP_IGNORE_citer] 95 | GOGP_GpFilePath=reg 96 | TYPENAME_L_SHORT=citer 97 | LOCK_COMMENT=// 98 | REVERSE_COMMENT=// 99 | NAME_INSTEAD= 100 | NAME_COMMENT_B= 101 | NAME_COMMENT_E= 102 | VALUE_TYPE=interface{} 103 | DEFAULT_REG_CNT=1024 104 | TYPENAME_L=const_interface 105 | TYPENAME_U=ConstInerface 106 | 107 | [GOGP_IGNORE_uint64] 108 | GOGP_GpFilePath=reg 109 | TYPENAME_L_SHORT=u64 110 | LOCK_COMMENT= 111 | REVERSE_COMMENT=// 112 | NAME_INSTEAD= 113 | NAME_COMMENT_B= 114 | NAME_COMMENT_E= 115 | VALUE_TYPE=uint64 116 | DEFAULT_REG_CNT=1024 117 | TYPENAME_L=uint64 118 | TYPENAME_U=Uint64 119 | 120 | [GOGP_IGNORE_cu64] 121 | GOGP_GpFilePath=reg 122 | TYPENAME_L_SHORT=const_u64 123 | LOCK_COMMENT=// 124 | REVERSE_COMMENT=// 125 | NAME_INSTEAD= 126 | NAME_COMMENT_B= 127 | NAME_COMMENT_E= 128 | VALUE_TYPE=uint64 129 | DEFAULT_REG_CNT=1024 130 | TYPENAME_L=const_uint64 131 | TYPENAME_U=ConstUint64 132 | 133 | [GOGP_IGNORE_noname_cu64] 134 | GOGP_GpFilePath=reg 135 | TYPENAME_L_SHORT=noname_cu64 136 | LOCK_COMMENT=// 137 | REVERSE_COMMENT=// 138 | NAME_INSTEAD=g_no_name 139 | NAME_COMMENT_B=/* 140 | NAME_COMMENT_E=*/ 141 | VALUE_TYPE=uint64 142 | DEFAULT_REG_CNT=1024 143 | TYPENAME_L=noname_cu64 144 | TYPENAME_U=NoNameConstUint64 145 | -------------------------------------------------------------------------------- /regable/regable.go: -------------------------------------------------------------------------------- 1 | //Assuming that all of the acts are registered in the initialization phase is complete 2 | //so do not use lock at regers 3 | 4 | //Package regable supply some ways of regist strings,bits variables,then operate then with ids 5 | package regable 6 | 7 | import ( 8 | "bytes" 9 | "fmt" 10 | 11 | acst "vipally.gmail.com/basic/consts" 12 | aerr "vipally.gmail.com/basic/errors" 13 | ) 14 | 15 | const ( 16 | g_invalid_id uint32 = 0 17 | g_max_id_bits = 32 18 | g_real_id_bits = 24 19 | g_get_real_id = (1<> (g_max_id_bits - g_real_id_bits) 20 | g_max_reger_id = 1<<(g_max_id_bits-g_real_id_bits) - 1 21 | g_max_real_id = 1< g_max_real_id { 38 | err = aerr.New(errid_max_reg_overflow) 39 | } 40 | return 41 | } 42 | 43 | func reg_show(f showRegFunc) { 44 | g_show_reg_funcs = append(g_show_reg_funcs, f) 45 | } 46 | func ShowAllRegs() string { 47 | str_head := fmt.Sprintf("[regable] locked:%v", g_reg_locked) 48 | var buf bytes.Buffer 49 | buf.WriteString(str_head) 50 | for _, f := range g_show_reg_funcs { 51 | buf.WriteString(acst.NEW_LINE) 52 | buf.WriteString(f()) 53 | } 54 | return buf.String() 55 | } 56 | 57 | func FinishReg() { 58 | g_reg_locked = true 59 | } 60 | 61 | func check_lock() (err error) { 62 | if g_reg_locked { 63 | s := "Reg when regs finished" 64 | err = fmt.Errorf(s) 65 | panic(s) 66 | } 67 | return 68 | } 69 | 70 | type regedId uint32 71 | 72 | func MakeRegedId(reger_id uint32, real_id uint32) uint32 { 73 | return reger_id<> g_real_id_bits) 77 | id = uint32(cp & g_get_real_id) 78 | return 79 | } 80 | func (cp regedId) id() (id uint32) { 81 | _, id = cp.ids() 82 | return 83 | } 84 | 85 | //----------------------------------------------- 86 | type RegList struct { 87 | list []*RegedObjMgr 88 | } 89 | type RegedObjMgr struct { 90 | id int //id of this mgr 91 | idmap map[RegedId]*RegedObj 92 | namemap map[string]RegedId 93 | } 94 | type RegedId uint //id of reged things 95 | type RegedObj struct { 96 | name string //name of this reg thing 97 | id RegedId 98 | ref uint //ref count,lock free operation 99 | contend string //real reged thing 100 | } 101 | -------------------------------------------------------------------------------- /regexp/regexp.go: -------------------------------------------------------------------------------- 1 | package regexp 2 | 3 | const ( 4 | //some predefined regular expression 5 | RegexpLineHead = "(?m)^\\s*" 6 | ) 7 | -------------------------------------------------------------------------------- /rpc/rpc.go: -------------------------------------------------------------------------------- 1 | package rpc 2 | -------------------------------------------------------------------------------- /sample/stl/stl.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gxlb/gx/6e49935b2516acf71d09a401c66350e7699f154c/sample/stl/stl.gpg -------------------------------------------------------------------------------- /script/lua/lua.go: -------------------------------------------------------------------------------- 1 | package lua 2 | -------------------------------------------------------------------------------- /sort/sort.go: -------------------------------------------------------------------------------- 1 | package sort 2 | -------------------------------------------------------------------------------- /stl/bit_set.go: -------------------------------------------------------------------------------- 1 | package stl 2 | 3 | //s set of bit for vistit 4 | type BitSet struct { 5 | d []uint 6 | } 7 | 8 | //func (this *BitSet) Bits(start, end uint) *Bits {} 9 | 10 | //operator of bits 11 | type Bits struct { 12 | start, end uint8 13 | d *BitSet 14 | } 15 | 16 | //func (this *Bits) Get() uint {} 17 | //func (this *Bits) Set(v uint) uint {} 18 | -------------------------------------------------------------------------------- /stl/doc.go: -------------------------------------------------------------------------------- 1 | // package stl implements template structures by gogp tool. 2 | // 3 | // sort_slice 4 | // stack 5 | // tree 6 | // toto: set/queue/dequeue/heap/vector/rbtree/dlist/slist 7 | package stl 8 | -------------------------------------------------------------------------------- /stl/functorcmp.gp_#inttreenodeb60b.go: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // 3 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 4 | // 5 | // This file was auto-generated by tool [github.com/vipally/gogp] 6 | // Last update at: [Sun Apr 02 2017 11:37:46] 7 | // Generate from: 8 | // [github.com/vipally/gx/stl/gp/functorcmp.gp] 9 | // [github.com/vipally/gx/stl/stl.gpg] [_tree_sort_slice_int] 10 | // 11 | // Tool [github.com/vipally/gogp] info: 12 | // CopyRight 2016 @Ally Dale. All rights reserved. 13 | // Author : Ally Dale(vipally@gmail.com) 14 | // Blog : http://blog.csdn.net/vipally 15 | // Site : https://github.com/vipally 16 | // BuildAt : [2017-04-01 23:37:40] 17 | // Version : 3.0.0.final 18 | // 19 | /////////////////////////////////////////////////////////////////// 20 | 21 | //this file is used to import by other gp files 22 | //it cannot use independently, simulation C++ stl functors 23 | 24 | package stl 25 | 26 | //cmp object, zero is Lesser 27 | type CmpIntTreeNode byte 28 | 29 | const ( 30 | CmpIntTreeNodeLesser CmpIntTreeNode = CMPLesser 31 | CmpIntTreeNodeGreater CmpIntTreeNode = CMPGreater 32 | ) 33 | 34 | //create cmp object by name 35 | func CreateCmpIntTreeNode(cmpName string) (r CmpIntTreeNode) { 36 | r = CmpIntTreeNodeLesser.CreateByName(cmpName) 37 | return 38 | } 39 | 40 | //uniformed global function 41 | func (me CmpIntTreeNode) F(left, right *IntTreeNode) (ok bool) { 42 | switch me { 43 | case CMPLesser: 44 | ok = me.less(left, right) 45 | case CMPGreater: 46 | ok = me.great(left, right) 47 | } 48 | return 49 | } 50 | 51 | //Lesser object 52 | func (me CmpIntTreeNode) Lesser() CmpIntTreeNode { return CMPLesser } 53 | 54 | //Greater object 55 | func (me CmpIntTreeNode) Greater() CmpIntTreeNode { return CMPGreater } 56 | 57 | //show as string 58 | func (me CmpIntTreeNode) String() (s string) { 59 | switch me { 60 | case CMPLesser: 61 | s = "Lesser" 62 | case CMPGreater: 63 | s = "Greater" 64 | default: 65 | s = "error cmp value" 66 | } 67 | return 68 | } 69 | 70 | //create by bool 71 | func (me CmpIntTreeNode) CreateByBool(bigFirst bool) (r CmpIntTreeNode) { 72 | if bigFirst { 73 | r = CMPGreater 74 | } else { 75 | r = CMPLesser 76 | } 77 | return 78 | } 79 | 80 | //create cmp object by name 81 | func (me CmpIntTreeNode) CreateByName(cmpName string) (r CmpIntTreeNode) { 82 | switch cmpName { 83 | case "": //default Lesser 84 | fallthrough 85 | case "Lesser": 86 | r = CMPLesser 87 | case "Greater": 88 | r = CMPGreater 89 | default: //unsupport name 90 | panic(cmpName) 91 | } 92 | return 93 | } 94 | 95 | //lesser operation 96 | func (me CmpIntTreeNode) less(left, right *IntTreeNode) (ok bool) { 97 | 98 | ok = left.Less(right) 99 | 100 | return 101 | } 102 | 103 | //Greater operation 104 | func (me CmpIntTreeNode) great(left, right *IntTreeNode) (ok bool) { 105 | 106 | ok = right.Less(left) 107 | 108 | return 109 | } 110 | -------------------------------------------------------------------------------- /stl/functorcmp.gp_int.go: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // 3 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 4 | // 5 | // This file was auto-generated by tool [github.com/vipally/gogp] 6 | // Last update at: [Sun Apr 02 2017 11:37:46] 7 | // Generate from: 8 | // [github.com/vipally/gx/stl/gp/functorcmp.gp] 9 | // [github.com/vipally/gx/stl/stl.gpg] [sort_slice_int] 10 | // 11 | // Tool [github.com/vipally/gogp] info: 12 | // CopyRight 2016 @Ally Dale. All rights reserved. 13 | // Author : Ally Dale(vipally@gmail.com) 14 | // Blog : http://blog.csdn.net/vipally 15 | // Site : https://github.com/vipally 16 | // BuildAt : [2017-04-01 23:37:40] 17 | // Version : 3.0.0.final 18 | // 19 | /////////////////////////////////////////////////////////////////// 20 | 21 | //this file is used to import by other gp files 22 | //it cannot use independently, simulation C++ stl functors 23 | 24 | package stl 25 | 26 | const ( 27 | CMPLesser = iota //default 28 | CMPGreater 29 | ) // 30 | 31 | //cmp object, zero is Lesser 32 | type CmpInt byte 33 | 34 | const ( 35 | CmpIntLesser CmpInt = CMPLesser 36 | CmpIntGreater CmpInt = CMPGreater 37 | ) 38 | 39 | //create cmp object by name 40 | func CreateCmpInt(cmpName string) (r CmpInt) { 41 | r = CmpIntLesser.CreateByName(cmpName) 42 | return 43 | } 44 | 45 | //uniformed global function 46 | func (me CmpInt) F(left, right int) (ok bool) { 47 | switch me { 48 | case CMPLesser: 49 | ok = me.less(left, right) 50 | case CMPGreater: 51 | ok = me.great(left, right) 52 | } 53 | return 54 | } 55 | 56 | //Lesser object 57 | func (me CmpInt) Lesser() CmpInt { return CMPLesser } 58 | 59 | //Greater object 60 | func (me CmpInt) Greater() CmpInt { return CMPGreater } 61 | 62 | //show as string 63 | func (me CmpInt) String() (s string) { 64 | switch me { 65 | case CMPLesser: 66 | s = "Lesser" 67 | case CMPGreater: 68 | s = "Greater" 69 | default: 70 | s = "error cmp value" 71 | } 72 | return 73 | } 74 | 75 | //create by bool 76 | func (me CmpInt) CreateByBool(bigFirst bool) (r CmpInt) { 77 | if bigFirst { 78 | r = CMPGreater 79 | } else { 80 | r = CMPLesser 81 | } 82 | return 83 | } 84 | 85 | //create cmp object by name 86 | func (me CmpInt) CreateByName(cmpName string) (r CmpInt) { 87 | switch cmpName { 88 | case "": //default Lesser 89 | fallthrough 90 | case "Lesser": 91 | r = CMPLesser 92 | case "Greater": 93 | r = CMPGreater 94 | default: //unsupport name 95 | panic(cmpName) 96 | } 97 | return 98 | } 99 | 100 | //lesser operation 101 | func (me CmpInt) less(left, right int) (ok bool) { 102 | 103 | ok = left < right 104 | 105 | return 106 | } 107 | 108 | //Greater operation 109 | func (me CmpInt) great(left, right int) (ok bool) { 110 | 111 | ok = right < left 112 | 113 | return 114 | } 115 | -------------------------------------------------------------------------------- /stl/gp/avl_tree.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | -------------------------------------------------------------------------------- /stl/gp/bstree.gp: -------------------------------------------------------------------------------- 1 | //#GOGP_IGNORE_BEGIN 2 | /////////////////////////////////////////////////////////////////// 3 | // 4 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 5 | // 6 | // This file was auto-generated by tool [github.com/vipally/gogp] 7 | // Last update at: [Thu Nov 24 2016 22:04:52] 8 | // Generate from: 9 | // [github.com/vipally/gx/stl/gp/bstree.gp.go] 10 | // [github.com/vipally/gx/stl/gp/gp.gpg] [GOGP_REVERSE_bstree] 11 | // 12 | // Tool [github.com/vipally/gogp] info: 13 | // CopyRight 2016 @Ally Dale. All rights reserved. 14 | // Author : Ally Dale(vipally@gmail.com) 15 | // Blog : http://blog.csdn.net/vipally 16 | // Site : https://github.com/vipally 17 | // BuildAt : [Oct 24 2016 20:25:45] 18 | // Version : 3.0.0.final 19 | // 20 | /////////////////////////////////////////////////////////////////// 21 | //#GOGP_IGNORE_END 22 | 23 | 24 | 25 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 26 | 27 | //#GOGP_REQUIRE(github.com/vipally/gx/stl/gp/functorcmp) 28 | 29 | //////////////////////////////////////////////////////////////////////////////// 30 | 31 | var gBSTreeGbl struct { 32 | cmp Cmp 33 | } 34 | 35 | func init() { 36 | gBSTreeGbl.cmp = gBSTreeGbl.cmp.CreateByName("#GOGP_GPGCFG(GOGP_DefaultCmpType)") 37 | } 38 | 39 | type BSTree struct { 40 | root *BSTreeNode 41 | } 42 | 43 | type BSTreeNode struct { 44 | key 45 | //#GOGP_IFDEF 46 | value 47 | //#GOGP_END_IF 48 | l, r *BSTreeNode 49 | } 50 | 51 | -------------------------------------------------------------------------------- /stl/gp/doc.go: -------------------------------------------------------------------------------- 1 | // package gp implements template structures by gogp tool. 2 | // 3 | // sort_slice 4 | // stack 5 | // tree 6 | // toto: set/queue/dequeue/heap/vector/rbtree/dlist/slist 7 | package gp 8 | -------------------------------------------------------------------------------- /stl/gp/fibheaps.gp.go: -------------------------------------------------------------------------------- 1 | //fibonacci-heap 2 | 3 | package gp 4 | -------------------------------------------------------------------------------- /stl/gp/functorcmp.gp: -------------------------------------------------------------------------------- 1 | //#GOGP_IGNORE_BEGIN 2 | /////////////////////////////////////////////////////////////////// 3 | // 4 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 5 | // 6 | // This file was auto-generated by tool [github.com/vipally/gogp] 7 | // Last update at: [Sat Apr 01 2017 22:48:08] 8 | // Generate from: 9 | // [github.com/vipally/gx/stl/gp/functorcmp.gp.go] 10 | // [github.com/vipally/gx/stl/gp/gp.gpg] [GOGP_REVERSE_functorcmp] 11 | // 12 | // Tool [github.com/vipally/gogp] info: 13 | // CopyRight 2016 @Ally Dale. All rights reserved. 14 | // Author : Ally Dale(vipally@gmail.com) 15 | // Blog : http://blog.csdn.net/vipally 16 | // Site : https://github.com/vipally 17 | // BuildAt : 18 | // Version : 3.0.0.final 19 | // 20 | /////////////////////////////////////////////////////////////////// 21 | //#GOGP_IGNORE_END 22 | 23 | //this file is used to import by other gp files 24 | //it cannot use independently, simulation C++ stl functors 25 | 26 | 27 | 28 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 29 | 30 | //#GOGP_IFDEF KEY_TYPE 31 | //#GOGP_REPLACE(, ) 32 | //#GOGP_ENDIF 33 | 34 | //#GOGP_ONCE 35 | const ( 36 | CMPLesser = iota //default 37 | CMPGreater 38 | ) // 39 | //#GOGP_END_ONCE 40 | 41 | //cmp object, zero is Lesser 42 | type Cmp byte 43 | 44 | const ( 45 | CmpLesser Cmp = CMPLesser 46 | CmpGreater Cmp = CMPGreater 47 | ) 48 | 49 | //create cmp object by name 50 | func CreateCmp(cmpName string) (r Cmp) { 51 | r = CmpLesser.CreateByName(cmpName) 52 | return 53 | } 54 | 55 | //uniformed global function 56 | func (me Cmp) F(left, right ) (ok bool) { 57 | switch me { 58 | case CMPLesser: 59 | ok = me.less(left, right) 60 | case CMPGreater: 61 | ok = me.great(left, right) 62 | } 63 | return 64 | } 65 | 66 | //Lesser object 67 | func (me Cmp) Lesser() Cmp { return CMPLesser } 68 | 69 | //Greater object 70 | func (me Cmp) Greater() Cmp { return CMPGreater } 71 | 72 | //show as string 73 | func (me Cmp) String() (s string) { 74 | switch me { 75 | case CMPLesser: 76 | s = "Lesser" 77 | case CMPGreater: 78 | s = "Greater" 79 | default: 80 | s = "error cmp value" 81 | } 82 | return 83 | } 84 | 85 | //create by bool 86 | func (me Cmp) CreateByBool(bigFirst bool) (r Cmp) { 87 | if bigFirst { 88 | r = CMPGreater 89 | } else { 90 | r = CMPLesser 91 | } 92 | return 93 | } 94 | 95 | //create cmp object by name 96 | func (me Cmp) CreateByName(cmpName string) (r Cmp) { 97 | switch cmpName { 98 | case "": //default Lesser 99 | fallthrough 100 | case "Lesser": 101 | r = CMPLesser 102 | case "Greater": 103 | r = CMPGreater 104 | default: //unsupport name 105 | panic(cmpName) 106 | } 107 | return 108 | } 109 | 110 | //lesser operation 111 | func (me Cmp) less(left, right ) (ok bool) { 112 | //#GOGP_IFDEF GOGP_HasCmpFunc 113 | ok = left.Less(right) 114 | //#GOGP_ELSE 115 | ok = left < right 116 | //#GOGP_ENDIF 117 | return 118 | } 119 | 120 | //Greater operation 121 | func (me Cmp) great(left, right ) (ok bool) { 122 | //#GOGP_IFDEF GOGP_HasCmpFunc 123 | ok = right.Less(left) 124 | //#GOGP_ELSE 125 | ok = right < left 126 | //#GOGP_ENDIF 127 | return 128 | } 129 | 130 | -------------------------------------------------------------------------------- /stl/gp/functorcmp.gp.go: -------------------------------------------------------------------------------- 1 | //this file is used to import by other gp files 2 | //it cannot use independently, simulation C++ stl functors 3 | 4 | package gp 5 | 6 | //#GOGP_FILE_BEGIN 7 | //#GOGP_IGNORE_BEGIN ///gogp_file_begin 8 | // 9 | /* //This line can be uncommented to disable all this file, and it doesn't effect to the .gp file 10 | // //If test or change .gp file required, comment it to modify and cmomile as normal go file 11 | // 12 | // This is a fake go code file 13 | // It is used to generate .gp file by gogp tool 14 | // Real go code file will be generated from .gp file 15 | // 16 | //#GOGP_IGNORE_END ///gogp_file_begin 17 | 18 | //#GOGP_IGNORE_BEGIN 19 | // #GOGP_REQUIRE(github.com/vipally/gx/stl/gp/fakedef,_) 20 | // #GOGP_REQUIRE(github.com/vipally/gx/stl/gp/factorcmp) 21 | //#GOGP_IGNORE_END 22 | 23 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 24 | //#GOGP_IGNORE_BEGIN ///require begin from(github.com/vipally/gogp/lib/fakedef) 25 | //these defines are used to make sure this fake go file can be compiled correctlly 26 | //and they will be removed from real go files 27 | //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 28 | 29 | type GOGPValueType int // 30 | func (this GOGPValueType) Less(o GOGPValueType) bool { return this < o } 31 | func (this GOGPValueType) Show() string { return "" } // 32 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 33 | //#GOGP_IGNORE_END ///require end from(github.com/vipally/gogp/lib/fakedef) 34 | 35 | //#GOGP_IFDEF KEY_TYPE 36 | //#GOGP_REPLACE(, ) 37 | //#GOGP_ENDIF 38 | 39 | //#GOGP_ONCE 40 | const ( 41 | CMPLesser = iota //default 42 | CMPGreater 43 | ) // 44 | //#GOGP_END_ONCE 45 | 46 | //cmp object, zero is Lesser 47 | type CmpGOGPGlobalNamePrefix byte 48 | 49 | const ( 50 | CmpGOGPGlobalNamePrefixLesser CmpGOGPGlobalNamePrefix = CMPLesser 51 | CmpGOGPGlobalNamePrefixGreater CmpGOGPGlobalNamePrefix = CMPGreater 52 | ) 53 | 54 | //create cmp object by name 55 | func CreateCmpGOGPGlobalNamePrefix(cmpName string) (r CmpGOGPGlobalNamePrefix) { 56 | r = CmpGOGPGlobalNamePrefixLesser.CreateByName(cmpName) 57 | return 58 | } 59 | 60 | //uniformed global function 61 | func (me CmpGOGPGlobalNamePrefix) F(left, right GOGPValueType) (ok bool) { 62 | switch me { 63 | case CMPLesser: 64 | ok = me.less(left, right) 65 | case CMPGreater: 66 | ok = me.great(left, right) 67 | } 68 | return 69 | } 70 | 71 | //Lesser object 72 | func (me CmpGOGPGlobalNamePrefix) Lesser() CmpGOGPGlobalNamePrefix { return CMPLesser } 73 | 74 | //Greater object 75 | func (me CmpGOGPGlobalNamePrefix) Greater() CmpGOGPGlobalNamePrefix { return CMPGreater } 76 | 77 | //show as string 78 | func (me CmpGOGPGlobalNamePrefix) String() (s string) { 79 | switch me { 80 | case CMPLesser: 81 | s = "Lesser" 82 | case CMPGreater: 83 | s = "Greater" 84 | default: 85 | s = "error cmp value" 86 | } 87 | return 88 | } 89 | 90 | //create by bool 91 | func (me CmpGOGPGlobalNamePrefix) CreateByBool(bigFirst bool) (r CmpGOGPGlobalNamePrefix) { 92 | if bigFirst { 93 | r = CMPGreater 94 | } else { 95 | r = CMPLesser 96 | } 97 | return 98 | } 99 | 100 | //create cmp object by name 101 | func (me CmpGOGPGlobalNamePrefix) CreateByName(cmpName string) (r CmpGOGPGlobalNamePrefix) { 102 | switch cmpName { 103 | case "": //default Lesser 104 | fallthrough 105 | case "Lesser": 106 | r = CMPLesser 107 | case "Greater": 108 | r = CMPGreater 109 | default: //unsupport name 110 | panic(cmpName) 111 | } 112 | return 113 | } 114 | 115 | //lesser operation 116 | func (me CmpGOGPGlobalNamePrefix) less(left, right GOGPValueType) (ok bool) { 117 | //#GOGP_IFDEF GOGP_HasCmpFunc 118 | ok = left.Less(right) 119 | //#GOGP_ELSE 120 | ok = left < right 121 | //#GOGP_ENDIF 122 | return 123 | } 124 | 125 | //Greater operation 126 | func (me CmpGOGPGlobalNamePrefix) great(left, right GOGPValueType) (ok bool) { 127 | //#GOGP_IFDEF GOGP_HasCmpFunc 128 | ok = right.Less(left) 129 | //#GOGP_ELSE 130 | ok = right < left 131 | //#GOGP_ENDIF 132 | return 133 | } 134 | 135 | //#GOGP_FILE_END 136 | //#GOGP_IGNORE_BEGIN ///gogp_file_end 137 | //*/ 138 | //#GOGP_IGNORE_END ///gogp_file_end 139 | -------------------------------------------------------------------------------- /stl/gp/gp.gpg: -------------------------------------------------------------------------------- 1 | ;this is exactlly an ini file 2 | ;this is an example of gogp reverse usage: generate .gp file form .gpg and .go file, sectionname must be lead with GOGP_REVERSE 3 | ;other section is used to do the next thing, gen .go file from .gpg and .gp file 4 | 5 | [GOGP_REVERSE_functorcmp] 6 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/functorcmp 7 | PACKAGE=package gp 8 | VALUE_TYPE=GOGPValueType 9 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix 10 | 11 | [GOGP_REVERSE_sort_slice] 12 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/sort_slice 13 | PACKAGE=package gp 14 | VALUE_TYPE=GOGPValueType 15 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix 16 | 17 | [GOGP_REVERSE_tree] 18 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/tree 19 | GOGP_HasCmpFunc=true 20 | GOGP_SectionSortSlice=_tree_sort_slice 21 | PACKAGE=package gp 22 | VALUE_TYPE=GOGPValueType 23 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix 24 | 25 | [_tree_sort_slice] 26 | GOGP_Ignore=true 27 | GOGP_DontSave=true 28 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/sort_slice 29 | GOGP_HasCmpFunc=true 30 | PACKAGE=package gp 31 | VALUE_TYPE=*GOGPGlobalNamePrefixTreeNode 32 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefixTreeNode 33 | 34 | [GOGP_REVERSE_stack] 35 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/stack 36 | GOGP_HasShow=false 37 | PACKAGE=package gp 38 | VALUE_TYPE=GOGPValueType 39 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix 40 | 41 | [GOGP_REVERSE_deque] 42 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/deque 43 | PACKAGE=package gp 44 | VALUE_TYPE=GOGPValueType 45 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix 46 | 47 | [GOGP_REVERSE_queue] 48 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/queue 49 | PACKAGE=package gp 50 | VALUE_TYPE=GOGPValueType 51 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix 52 | 53 | [GOGP_REVERSE_heap] 54 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/heap 55 | GOGP_ImproveSTL=false 56 | PACKAGE=package gp 57 | VALUE_TYPE=GOGPValueType 58 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix 59 | 60 | [GOGP_REVERSE_list] 61 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/list 62 | PACKAGE=package gp 63 | VALUE_TYPE=GOGPValueType 64 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix 65 | 66 | [GOGP_REVERSE_slist] 67 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/slist 68 | PACKAGE=package gp 69 | VALUE_TYPE=GOGPValueType 70 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix 71 | 72 | [GOGP_REVERSE_rbtree] 73 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/rbtree 74 | PACKAGE=package gp 75 | KEY_TYPE=GOGPKeyType 76 | VALUE_TYPE=GOGPValueType 77 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix 78 | 79 | [GOGP_REVERSE_lfqueue] 80 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/lfqueue 81 | PACKAGE=package gp 82 | VALUE_TYPE=GOGPValueType 83 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix 84 | 85 | [GOGP_REVERSE_lfdeque] 86 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/lfdeque 87 | PACKAGE=package gp 88 | VALUE_TYPE=GOGPValueType 89 | GLOBAL_NAME_PREFIX=GOGPGlobalNamePrefix 90 | -------------------------------------------------------------------------------- /stl/gp/lfqueue.gp: -------------------------------------------------------------------------------- 1 | //#GOGP_IGNORE_BEGIN 2 | /////////////////////////////////////////////////////////////////// 3 | // 4 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 5 | // 6 | // This file was auto-generated by tool [github.com/vipally/gogp] 7 | // Last update at: [Sat Apr 01 2017 22:48:08] 8 | // Generate from: 9 | // [github.com/vipally/gx/stl/gp/lfqueue.gp.go] 10 | // [github.com/vipally/gx/stl/gp/gp.gpg] [GOGP_REVERSE_lfqueue] 11 | // 12 | // Tool [github.com/vipally/gogp] info: 13 | // CopyRight 2016 @Ally Dale. All rights reserved. 14 | // Author : Ally Dale(vipally@gmail.com) 15 | // Blog : http://blog.csdn.net/vipally 16 | // Site : https://github.com/vipally 17 | // BuildAt : 18 | // Version : 3.0.0.final 19 | // 20 | /////////////////////////////////////////////////////////////////// 21 | //#GOGP_IGNORE_END 22 | 23 | 24 | 25 | import ( 26 | "sync/atomic" 27 | "unsafe" 28 | ) 29 | 30 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 31 | 32 | //list node 33 | type LFQueueNode struct { 34 | val 35 | next unsafe.Pointer 36 | } 37 | 38 | //single-way link list object 39 | type LFQueue struct { 40 | head LFQueueNode //head is a dummy node, not a pionter 41 | //tail unsafe.Pointer 42 | size int32 43 | } 44 | 45 | func (this *LFQueue) makeNode(v ) (n *LFQueueNode) { 46 | n = &LFQueueNode{} 47 | n.val = v 48 | n.next = nil 49 | return 50 | } 51 | 52 | func (this *LFQueue) PushFront(v ) bool { 53 | n := this.makeNode(v) 54 | p := unsafe.Pointer(n) 55 | for { 56 | n.next = atomic.LoadPointer(&this.head.next) 57 | if atomic.CompareAndSwapPointer(&this.head.next, n.next, p) { 58 | break 59 | } 60 | } 61 | // if atomic.LoadPointer(&this.tail) == nil { 62 | // atomic.StorePointer(&this.tail, p) 63 | // } 64 | atomic.AddInt32(&this.size, 1) 65 | return true 66 | } 67 | 68 | //func (this *LFQueue) PushBack(v ) bool { 69 | // n := this.makeNode(v) 70 | // p := unsafe.Pointer(n) 71 | // for { 72 | // t := atomic.LoadPointer(&this.tail) 73 | // if t == nil { 74 | // atomic.CompareAndSwapPointer(&this.tail, nil, p) 75 | // if atomic.CompareAndSwapPointer(&this.head.next, nil, p) { 76 | // break 77 | // } 78 | // } else { 79 | // tt := (*LFQueueNode)(t) 80 | // if atomic.CompareAndSwapPointer(&this.tail, t, p) { 81 | // tt.next = p 82 | // break 83 | // } 84 | // } 85 | // } 86 | // atomic.AddInt32(&this.size, 1) 87 | // return true 88 | //} 89 | 90 | func (this *LFQueue) PopFront() (v , ok bool) { 91 | for { 92 | t := atomic.LoadPointer(&this.head.next) 93 | if t == nil { 94 | break 95 | } else { 96 | n := (*LFQueueNode)(t) 97 | next := n.next 98 | if atomic.CompareAndSwapPointer(&this.head.next, t, next) { 99 | v, ok = n.val, true 100 | break 101 | } 102 | } 103 | } 104 | atomic.AddInt32(&this.size, -1) 105 | return 106 | } 107 | 108 | func (this *LFQueue) Clear() { 109 | atomic.StorePointer(&this.head.next, nil) 110 | //atomic.StorePointer(&this.tail, nil) 111 | } 112 | 113 | //func (this *LFQueue) PopBack() (v , ok bool) { return } 114 | 115 | func (this *LFQueue) Size() int { 116 | return int(atomic.LoadInt32(&this.size)) 117 | } 118 | 119 | func (this *LFQueue) Empty() bool { 120 | return atomic.LoadPointer(&this.head.next) == nil 121 | } 122 | 123 | -------------------------------------------------------------------------------- /stl/gp/lfqueue.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | 3 | //#GOGP_FILE_BEGIN 4 | //#GOGP_IGNORE_BEGIN ///gogp_file_begin 5 | // 6 | /* //This line can be uncommented to disable all this file, and it doesn't effect to the .gp file 7 | // //If test or change .gp file required, comment it to modify and cmomile as normal go file 8 | // 9 | // This is a fake go code file 10 | // It is used to generate .gp file by gogp tool 11 | // Real go code file will be generated from .gp file 12 | // 13 | //#GOGP_IGNORE_END ///gogp_file_begin 14 | 15 | import ( 16 | "sync/atomic" 17 | "unsafe" 18 | ) 19 | 20 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 21 | //#GOGP_IGNORE_BEGIN ///require begin from(github.com/vipally/gogp/lib/fakedef) 22 | //these defines are used to make sure this fake go file can be compiled correctlly 23 | //and they will be removed from real go files 24 | //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 25 | 26 | type GOGPValueType int // 27 | func (this GOGPValueType) Less(o GOGPValueType) bool { return this < o } 28 | func (this GOGPValueType) Show() string { return "" } // 29 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 30 | //#GOGP_IGNORE_END ///require end from(github.com/vipally/gogp/lib/fakedef) 31 | 32 | //list node 33 | type GOGPGlobalNamePrefixLFQueueNode struct { 34 | val GOGPValueType 35 | next unsafe.Pointer 36 | } 37 | 38 | //single-way link list object 39 | type GOGPGlobalNamePrefixLFQueue struct { 40 | head GOGPGlobalNamePrefixLFQueueNode //head is a dummy node, not a pionter 41 | //tail unsafe.Pointer 42 | size int32 43 | } 44 | 45 | func (this *GOGPGlobalNamePrefixLFQueue) makeNode(v GOGPValueType) (n *GOGPGlobalNamePrefixLFQueueNode) { 46 | n = &GOGPGlobalNamePrefixLFQueueNode{} 47 | n.val = v 48 | n.next = nil 49 | return 50 | } 51 | 52 | func (this *GOGPGlobalNamePrefixLFQueue) PushFront(v GOGPValueType) bool { 53 | n := this.makeNode(v) 54 | p := unsafe.Pointer(n) 55 | for { 56 | n.next = atomic.LoadPointer(&this.head.next) 57 | if atomic.CompareAndSwapPointer(&this.head.next, n.next, p) { 58 | break 59 | } 60 | } 61 | // if atomic.LoadPointer(&this.tail) == nil { 62 | // atomic.StorePointer(&this.tail, p) 63 | // } 64 | atomic.AddInt32(&this.size, 1) 65 | return true 66 | } 67 | 68 | //func (this *GOGPGlobalNamePrefixLFQueue) PushBack(v GOGPValueType) bool { 69 | // n := this.makeNode(v) 70 | // p := unsafe.Pointer(n) 71 | // for { 72 | // t := atomic.LoadPointer(&this.tail) 73 | // if t == nil { 74 | // atomic.CompareAndSwapPointer(&this.tail, nil, p) 75 | // if atomic.CompareAndSwapPointer(&this.head.next, nil, p) { 76 | // break 77 | // } 78 | // } else { 79 | // tt := (*GOGPGlobalNamePrefixLFQueueNode)(t) 80 | // if atomic.CompareAndSwapPointer(&this.tail, t, p) { 81 | // tt.next = p 82 | // break 83 | // } 84 | // } 85 | // } 86 | // atomic.AddInt32(&this.size, 1) 87 | // return true 88 | //} 89 | 90 | func (this *GOGPGlobalNamePrefixLFQueue) PopFront() (v GOGPValueType, ok bool) { 91 | for { 92 | t := atomic.LoadPointer(&this.head.next) 93 | if t == nil { 94 | break 95 | } else { 96 | n := (*GOGPGlobalNamePrefixLFQueueNode)(t) 97 | next := n.next 98 | if atomic.CompareAndSwapPointer(&this.head.next, t, next) { 99 | v, ok = n.val, true 100 | break 101 | } 102 | } 103 | } 104 | atomic.AddInt32(&this.size, -1) 105 | return 106 | } 107 | 108 | func (this *GOGPGlobalNamePrefixLFQueue) Clear() { 109 | atomic.StorePointer(&this.head.next, nil) 110 | //atomic.StorePointer(&this.tail, nil) 111 | } 112 | 113 | //func (this *GOGPGlobalNamePrefixLFQueue) PopBack() (v GOGPValueType, ok bool) { return } 114 | 115 | func (this *GOGPGlobalNamePrefixLFQueue) Size() int { 116 | return int(atomic.LoadInt32(&this.size)) 117 | } 118 | 119 | func (this *GOGPGlobalNamePrefixLFQueue) Empty() bool { 120 | return atomic.LoadPointer(&this.head.next) == nil 121 | } 122 | 123 | //#GOGP_FILE_END 124 | //#GOGP_IGNORE_BEGIN ///gogp_file_end 125 | //*/ 126 | //#GOGP_IGNORE_END ///gogp_file_end 127 | -------------------------------------------------------------------------------- /stl/gp/map.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | -------------------------------------------------------------------------------- /stl/gp/multi_map.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | -------------------------------------------------------------------------------- /stl/gp/multi_set.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | -------------------------------------------------------------------------------- /stl/gp/priqueue.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | -------------------------------------------------------------------------------- /stl/gp/queue.gp: -------------------------------------------------------------------------------- 1 | //#GOGP_IGNORE_BEGIN 2 | /////////////////////////////////////////////////////////////////// 3 | // 4 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 5 | // 6 | // This file was auto-generated by tool [github.com/vipally/gogp] 7 | // Last update at: [Sat Apr 01 2017 22:48:08] 8 | // Generate from: 9 | // [github.com/vipally/gx/stl/gp/queue.gp.go] 10 | // [github.com/vipally/gx/stl/gp/gp.gpg] [GOGP_REVERSE_queue] 11 | // 12 | // Tool [github.com/vipally/gogp] info: 13 | // CopyRight 2016 @Ally Dale. All rights reserved. 14 | // Author : Ally Dale(vipally@gmail.com) 15 | // Blog : http://blog.csdn.net/vipally 16 | // Site : https://github.com/vipally 17 | // BuildAt : 18 | // Version : 3.0.0.final 19 | // 20 | /////////////////////////////////////////////////////////////////// 21 | //#GOGP_IGNORE_END 22 | 23 | 24 | 25 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 26 | 27 | //#GOGP_REQUIRE(github.com/vipally/gx/stl/gp/functorcmp) 28 | 29 | //////////////////////////////////////////////////////////////////////////////// 30 | 31 | //queue object 32 | type Queue struct { 33 | //real data is [head,tail) 34 | //buffer d is cycle, that is to say, next(len(d)-1)=0, prev(0)=len(d)-1 35 | //so if tail 39 | } 40 | 41 | //new object 42 | func NewGOGPQueueNamePrefixQueue(bufSize int) *Queue { 43 | r := &Queue{} 44 | r.Init(bufSize) 45 | return r 46 | } 47 | 48 | //init 49 | func (this *Queue) Init(bufSize int) { 50 | if nil == this.d { 51 | if bufSize <= 0 { 52 | bufSize = 8 //default buffer size 53 | } 54 | this.newBuf(bufSize) 55 | } 56 | this.Clear() 57 | return 58 | } 59 | 60 | //create new buffer 61 | func (this *Queue) newBuf(bufSize int) { 62 | if bufSize > 0 { 63 | this.d = make([], bufSize, bufSize) //the same cap and len 64 | } 65 | } 66 | 67 | //clear 68 | func (this *Queue) Clear() { 69 | this.head, this.tail = 0, 0 70 | } 71 | 72 | //push to back of queue 73 | func (this *Queue) Push(v ) (ok bool) { 74 | if ok = true; ok { 75 | if nil == this.d { //init if needed 76 | this.Init(-1) 77 | } 78 | this.d[this.tail] = v 79 | if this.tail++; this.tail >= this.Cap() { 80 | this.tail = 0 81 | if this.tail == this.head { //tail catch up head, buffer full 82 | oldCap := this.Cap() 83 | d := this.d 84 | this.newBuf(oldCap * 2) 85 | h := copy(this.d, d[this.head:]) 86 | t := copy(this.d[:h], d[:this.tail]) 87 | this.head, this.tail = 0, h+t 88 | } 89 | } 90 | } 91 | return 92 | } 93 | 94 | //pop front of queue 95 | func (this *Queue) Pop() (front , ok bool) { 96 | if ok = this.head != this.tail; ok { 97 | front = this.d[this.head] 98 | if this.head++; this.head >= this.Cap() && this.head != this.tail { 99 | this.head = 0 100 | } 101 | } 102 | return 103 | } 104 | 105 | //front data 106 | func (this *Queue) Front() (front , ok bool) { 107 | if ok = this.head != this.tail; ok { 108 | front = this.d[this.head] 109 | } 110 | return 111 | } 112 | 113 | //back data 114 | func (this *Queue) Back() (back , ok bool) { 115 | if ok = this.head != this.tail; ok { 116 | t := this.tail - 1 117 | if t < 0 { 118 | t = this.Cap() - 1 119 | } 120 | back = this.d[t] 121 | } 122 | return 123 | } 124 | 125 | //shrink data buffer if necessary 126 | func (this *Queue) Shrink() (ok bool) { 127 | oldCap := this.Cap() 128 | oldSize := this.Size() 129 | if ok := oldCap > 8 && oldCap >= 3*oldSize; ok { //leave at least 8 elem space 130 | d := this.d 131 | this.newBuf(oldSize / 2) 132 | if this.tail >= this.head { 133 | copy(this.d, d[this.head:this.tail]) 134 | this.tail -= this.head 135 | this.head = 0 136 | } else { 137 | h := copy(this.d, d[this.head:]) 138 | t := copy(this.d[:h], d[:this.tail]) 139 | this.head, this.tail = 0, h+t 140 | } 141 | } 142 | return 143 | } 144 | 145 | //func (this *GOGPDequeNamePrefixDeque) Sort() {} 146 | 147 | //data buffer size 148 | func (this *Queue) Cap() int { 149 | return len(this.d) 150 | } 151 | 152 | //size of queue 153 | func (this *Queue) Size() (size int) { 154 | if this.tail >= this.head { 155 | size = this.tail - this.head 156 | } else { 157 | size = this.Cap() - this.head + this.tail 158 | } 159 | return 160 | } 161 | 162 | //if queue is empty 163 | func (this *Queue) Empty() bool { 164 | return this.Size() == 0 165 | } 166 | 167 | ////show 168 | //func (this *GOGPQueueNamePrefixQueue) Show() string { 169 | // var b show_bytes.Buffer 170 | // b.WriteByte('[') 171 | // for i := this.head; i != this.tail; i++ { 172 | // if i >= this.Cap() { 173 | // i = 0 174 | // } 175 | // v = this.v[i] 176 | // b.WriteString(v.Show()) 177 | // b.WriteByte(',') 178 | // } 179 | // if this.Depth() > 0 { 180 | // b.Truncate(b.Len() - 1) //remove last ',' 181 | // } 182 | // b.WriteByte(']') 183 | // return b.String() 184 | //} 185 | 186 | -------------------------------------------------------------------------------- /stl/gp/ringbuffer.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | 3 | //#GOGP_FILE_BEGIN 1 4 | 5 | import ( 6 | "sync/atomic" 7 | ) 8 | 9 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 10 | 11 | //#GOGP_ONCE 12 | const ( 13 | defaultRingBufferCap = 8 14 | ) // 15 | //#GOGP_END_ONCE 16 | 17 | //refer http://lmax-exchange.github.io/disruptor/ 18 | //RingBuffer object 19 | //Thread-safe, Use atomic algorithm to avoid Mutex lock 20 | type GOGPGlobalNamePrefixRingBuffer struct { 21 | //real data is [head,tail) 22 | //buffer d is cycle, that is to say, next(len(d)-1)=0, prev(0)=len(d)-1 23 | //so if tail 0 { 55 | this.d = make([]GOGPValueType, bufSize, bufSize) //the same cap and len 56 | } 57 | } 58 | 59 | //push to back of deque, will block when full 60 | func (this *GOGPGlobalNamePrefixRingBuffer) MustPush(v GOGPValueType) (ok bool) { 61 | tail_r := atomic.AddUint64(&this.tail_r, 1) 62 | old := tail_r - 1 63 | for tail_r > atomic.LoadUint64(&this.head)+this.mask+1 { //wait while full, body do nothing 64 | } 65 | 66 | idx := old & this.mask 67 | this.d[idx], ok = v, true 68 | for !atomic.CompareAndSwapUint64(&this.tail, old, tail_r) { //body do nothing 69 | } 70 | return 71 | } 72 | 73 | //pop front of deque, will block when empty 74 | func (this *GOGPGlobalNamePrefixRingBuffer) MustPop() (val GOGPValueType, ok bool) { 75 | head_r := atomic.AddUint64(&this.head_r, 1) 76 | old := head_r - 1 77 | for old >= atomic.LoadUint64(&this.tail) { //wait while empty, body do nothing 78 | } 79 | 80 | idx := old & this.mask 81 | val, ok = this.d[idx], true 82 | for !atomic.CompareAndSwapUint64(&this.head, old, head_r) { //body do nothing 83 | } 84 | return 85 | } 86 | 87 | //push to back of deque, will return false when full 88 | func (this *GOGPGlobalNamePrefixRingBuffer) Push(v GOGPValueType) (ok bool) { 89 | tail_r := atomic.AddUint64(&this.tail_r, 1) 90 | idx := tail_r & this.mask 91 | this.d[idx] = v 92 | for old := tail_r - 1; !atomic.CompareAndSwapUint64(&this.tail, old, tail_r); { //body do nothing 93 | } 94 | return 95 | } 96 | 97 | //pop front of deque, will return false when empty 98 | func (this *GOGPGlobalNamePrefixRingBuffer) Pop() (val GOGPValueType, ok bool) { 99 | head_r := atomic.AddUint64(&this.head_r, 1) 100 | idx := head_r & this.mask 101 | val, ok = this.d[idx], true 102 | for old := head_r - 1; !atomic.CompareAndSwapUint64(&this.head, old, head_r); { //body do nothing 103 | } 104 | return 105 | } 106 | 107 | //data buffer size 108 | func (this *GOGPGlobalNamePrefixRingBuffer) Cap() uint32 { 109 | return uint32(len(this.d)) 110 | } 111 | 112 | //size of queue 113 | func (this *GOGPGlobalNamePrefixRingBuffer) Size() (size int) { 114 | return int(atomic.LoadUint64(&this.tail) - atomic.LoadUint64(&this.head)) 115 | } 116 | 117 | //Busy returns how many times Push when busy 118 | func (this *GOGPGlobalNamePrefixRingBuffer) Busy() uint64 { 119 | return atomic.LoadUint64(&this.busy) 120 | } 121 | 122 | //if queue is empty 123 | func (this *GOGPGlobalNamePrefixRingBuffer) Empty() bool { 124 | return this.Size() == 0 125 | } 126 | 127 | //#GOGP_FILE_END 128 | -------------------------------------------------------------------------------- /stl/gp/set.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | -------------------------------------------------------------------------------- /stl/gp/sort_slice.gp: -------------------------------------------------------------------------------- 1 | //#GOGP_IGNORE_BEGIN 2 | /////////////////////////////////////////////////////////////////// 3 | // 4 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 5 | // 6 | // This file was auto-generated by tool [github.com/vipally/gogp] 7 | // Last update at: [Sat Apr 01 2017 22:48:08] 8 | // Generate from: 9 | // [github.com/vipally/gx/stl/gp/sort_slice.gp.go] 10 | // [github.com/vipally/gx/stl/gp/gp.gpg] [GOGP_REVERSE_sort_slice] 11 | // 12 | // Tool [github.com/vipally/gogp] info: 13 | // CopyRight 2016 @Ally Dale. All rights reserved. 14 | // Author : Ally Dale(vipally@gmail.com) 15 | // Blog : http://blog.csdn.net/vipally 16 | // Site : https://github.com/vipally 17 | // BuildAt : 18 | // Version : 3.0.0.final 19 | // 20 | /////////////////////////////////////////////////////////////////// 21 | //#GOGP_IGNORE_END 22 | 23 | //this file define a template type for sort 24 | 25 | 26 | 27 | import "sort" 28 | 29 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 30 | 31 | //#GOGP_REQUIRE(github.com/vipally/gx/stl/gp/functorcmp) 32 | 33 | //////////////////////////////////////////////////////////////////////////////// 34 | 35 | var gSortSliceGbl struct { 36 | cmp Cmp 37 | } 38 | 39 | func init() { 40 | gSortSliceGbl.cmp = gSortSliceGbl.cmp.CreateByName("#GOGP_GPGCFG(GOGP_DefaultCmpType)") 41 | } 42 | 43 | //new sort object 44 | func NewSortSlice(capacity int) *SortSlice { 45 | p := &SortSlice{} 46 | p.Init(capacity) 47 | return p 48 | } 49 | 50 | //sort slice 51 | type SortSlice struct { 52 | d [] 53 | } 54 | 55 | //init 56 | func (this *SortSlice) Init(capacity int) { 57 | this.d = make([], 0, capacity) 58 | } 59 | 60 | //sort 61 | func (this *SortSlice) Sort() { 62 | sort.Sort(this) 63 | } 64 | 65 | //data buffer 66 | func (this *SortSlice) Buffer() [] { 67 | return this.d 68 | } 69 | 70 | //push 71 | func (this *SortSlice) Push(v ) int { 72 | this.d = append(this.d, v) 73 | return this.Len() 74 | } 75 | 76 | //insert 77 | func (this *SortSlice) Insert(v , idx int) int { 78 | if idx >= 0 && idx < this.Len() { 79 | right := this.d[idx+1:] 80 | this.d = append(this.d[:idx], v) 81 | this.d = append(this.d, right...) 82 | } else { 83 | this.d = append(this.d, v) 84 | } 85 | return this.Len() 86 | } 87 | 88 | //remove 89 | func (this *SortSlice) Remove(idx int) (r , ok bool) { 90 | if r, ok = this.Get(idx); ok { 91 | right := this.d[idx+1:] 92 | this.d = append(this.d[:idx], right...) 93 | } 94 | return 95 | } 96 | 97 | //pop 98 | func (this *SortSlice) Pop() (r , ok bool) { 99 | if ok = len(this.d) > 0; ok { 100 | r = (this.d)[len(this.d)-1] 101 | } 102 | this.d = (this.d)[:len(this.d)-1] 103 | return 104 | } 105 | 106 | //get 107 | func (this *SortSlice) Get(idx int) (r , ok bool) { 108 | if ok = idx >= 0 && idx < this.Len(); ok { 109 | r = this.d[idx] 110 | } 111 | return 112 | } 113 | 114 | //must get 115 | func (this *SortSlice) MustGet(idx int) (r ) { 116 | ok := false 117 | if r, ok = this.Get(idx); !ok { 118 | panic(idx) 119 | } 120 | return 121 | } 122 | 123 | //len 124 | func (this *SortSlice) Len() int { 125 | return len(this.d) 126 | } 127 | 128 | //sort by Hash decend,the larger one first 129 | func (this *SortSlice) Less(i, j int) (ok bool) { 130 | l, r := (this.d)[i], (this.d)[j] 131 | return gSortSliceGbl.cmp.F(l, r) 132 | } 133 | 134 | //swap 135 | func (this *SortSlice) Swap(i, j int) { 136 | (this.d)[i], (this.d)[j] = (this.d)[j], (this.d)[i] 137 | } 138 | 139 | -------------------------------------------------------------------------------- /stl/gp/stack.gp: -------------------------------------------------------------------------------- 1 | //#GOGP_IGNORE_BEGIN 2 | /////////////////////////////////////////////////////////////////// 3 | // 4 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 5 | // 6 | // This file was auto-generated by tool [github.com/vipally/gogp] 7 | // Last update at: [Sat Apr 01 2017 22:48:08] 8 | // Generate from: 9 | // [github.com/vipally/gx/stl/gp/stack.gp.go] 10 | // [github.com/vipally/gx/stl/gp/gp.gpg] [GOGP_REVERSE_stack] 11 | // 12 | // Tool [github.com/vipally/gogp] info: 13 | // CopyRight 2016 @Ally Dale. All rights reserved. 14 | // Author : Ally Dale(vipally@gmail.com) 15 | // Blog : http://blog.csdn.net/vipally 16 | // Site : https://github.com/vipally 17 | // BuildAt : 18 | // Version : 3.0.0.final 19 | // 20 | /////////////////////////////////////////////////////////////////// 21 | //#GOGP_IGNORE_END 22 | 23 | 24 | 25 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 26 | 27 | //////////////////////////////////////////////////////////////////////////////// 28 | 29 | //stack object 30 | type Stack struct { 31 | d [] 32 | } 33 | 34 | //new object 35 | func NewGOGPStackNamePrefixStack(bufSize int) *Stack { 36 | r := &Stack{} 37 | r.Init(bufSize) 38 | return r 39 | } 40 | 41 | //init 42 | func (this *Stack) Init(bufSize int) { 43 | if nil == this.d { 44 | if -1 == bufSize { 45 | bufSize = 10 46 | } 47 | if bufSize > 0 { 48 | this.d = make([], 0, bufSize) 49 | } 50 | } 51 | this.d = this.d[:0] 52 | return 53 | } 54 | 55 | //clear 56 | func (this *Stack) Clear() { 57 | this.Init(-1) 58 | } 59 | 60 | //push v to top of stack 61 | func (this *Stack) Push(v ) (ok bool) { 62 | if ok = true; ok { 63 | this.d = append(this.d, v) 64 | } 65 | return 66 | } 67 | 68 | //pop top of stack 69 | func (this *Stack) Pop() (top , ok bool) { 70 | if top, ok = this.Top(); ok { 71 | this.d = this.d[:this.Size()-1] 72 | } 73 | return 74 | } 75 | 76 | //get top of stack 77 | func (this *Stack) Top() (top , ok bool) { 78 | d := this.Size() 79 | if d > 0 { 80 | top = this.d[d-1] 81 | ok = true 82 | } 83 | return 84 | 85 | } 86 | 87 | //size of stack 88 | func (this *Stack) Size() int { 89 | return len(this.d) 90 | } 91 | 92 | //is stack is empty 93 | func (this *Stack) Empty() bool { 94 | return this.Size() == 0 95 | } 96 | 97 | ////show 98 | //func (this *Stack) Show() string { 99 | // var b show_bytes.Buffer 100 | // b.WriteByte('[') 101 | // for _, v := range this.d { 102 | // b.WriteString(v.Show()) 103 | // b.WriteByte(',') 104 | // } 105 | // if this.Size() > 0 { 106 | // b.Truncate(b.Len() - 1) //remove last ',' 107 | // } 108 | // b.WriteByte(']') 109 | // return b.String() 110 | //} // 111 | 112 | -------------------------------------------------------------------------------- /stl/gp/stack.gp.go: -------------------------------------------------------------------------------- 1 | package gp 2 | 3 | //#GOGP_FILE_BEGIN 4 | //#GOGP_IGNORE_BEGIN ///gogp_file_begin 5 | // 6 | /* //This line can be uncommented to disable all this file, and it doesn't effect to the .gp file 7 | // //If test or change .gp file required, comment it to modify and cmomile as normal go file 8 | // 9 | // This is a fake go code file 10 | // It is used to generate .gp file by gogp tool 11 | // Real go code file will be generated from .gp file 12 | // 13 | //#GOGP_IGNORE_END ///gogp_file_begin 14 | 15 | //#GOGP_REQUIRE(github.com/vipally/gogp/lib/fakedef,_) 16 | //#GOGP_IGNORE_BEGIN ///require begin from(github.com/vipally/gogp/lib/fakedef) 17 | //these defines are used to make sure this fake go file can be compiled correctlly 18 | //and they will be removed from real go files 19 | //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 20 | 21 | type GOGPValueType int // 22 | func (this GOGPValueType) Less(o GOGPValueType) bool { return this < o } 23 | func (this GOGPValueType) Show() string { return "" } // 24 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 25 | //#GOGP_IGNORE_END ///require end from(github.com/vipally/gogp/lib/fakedef) 26 | 27 | //////////////////////////////////////////////////////////////////////////////// 28 | 29 | //stack object 30 | type GOGPGlobalNamePrefixStack struct { 31 | d []GOGPValueType 32 | } 33 | 34 | //new object 35 | func NewGOGPStackNamePrefixStack(bufSize int) *GOGPGlobalNamePrefixStack { 36 | r := &GOGPGlobalNamePrefixStack{} 37 | r.Init(bufSize) 38 | return r 39 | } 40 | 41 | //init 42 | func (this *GOGPGlobalNamePrefixStack) Init(bufSize int) { 43 | if nil == this.d { 44 | if -1 == bufSize { 45 | bufSize = 10 46 | } 47 | if bufSize > 0 { 48 | this.d = make([]GOGPValueType, 0, bufSize) 49 | } 50 | } 51 | this.d = this.d[:0] 52 | return 53 | } 54 | 55 | //clear 56 | func (this *GOGPGlobalNamePrefixStack) Clear() { 57 | this.Init(-1) 58 | } 59 | 60 | //push v to top of stack 61 | func (this *GOGPGlobalNamePrefixStack) Push(v GOGPValueType) (ok bool) { 62 | if ok = true; ok { 63 | this.d = append(this.d, v) 64 | } 65 | return 66 | } 67 | 68 | //pop top of stack 69 | func (this *GOGPGlobalNamePrefixStack) Pop() (top GOGPValueType, ok bool) { 70 | if top, ok = this.Top(); ok { 71 | this.d = this.d[:this.Size()-1] 72 | } 73 | return 74 | } 75 | 76 | //get top of stack 77 | func (this *GOGPGlobalNamePrefixStack) Top() (top GOGPValueType, ok bool) { 78 | d := this.Size() 79 | if d > 0 { 80 | top = this.d[d-1] 81 | ok = true 82 | } 83 | return 84 | 85 | } 86 | 87 | //size of stack 88 | func (this *GOGPGlobalNamePrefixStack) Size() int { 89 | return len(this.d) 90 | } 91 | 92 | //is stack is empty 93 | func (this *GOGPGlobalNamePrefixStack) Empty() bool { 94 | return this.Size() == 0 95 | } 96 | 97 | ////show 98 | //func (this *GOGPGlobalNamePrefixStack) Show() string { 99 | // var b show_bytes.Buffer 100 | // b.WriteByte('[') 101 | // for _, v := range this.d { 102 | // b.WriteString(v.Show()) 103 | // b.WriteByte(',') 104 | // } 105 | // if this.Size() > 0 { 106 | // b.Truncate(b.Len() - 1) //remove last ',' 107 | // } 108 | // b.WriteByte(']') 109 | // return b.String() 110 | //} // 111 | 112 | //#GOGP_FILE_END 113 | //#GOGP_IGNORE_BEGIN ///gogp_file_end 114 | //*/ 115 | //#GOGP_IGNORE_END ///gogp_file_end 116 | -------------------------------------------------------------------------------- /stl/heap.gp_int.go: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // 3 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 4 | // 5 | // This file was auto-generated by tool [github.com/vipally/gogp] 6 | // Last update at: [Sat Apr 01 2017 22:48:09] 7 | // Generate from: 8 | // [github.com/vipally/gx/stl/gp/heap.gp] 9 | // [github.com/vipally/gx/stl/stl.gpg] [heap_int] 10 | // 11 | // Tool [github.com/vipally/gogp] info: 12 | // CopyRight 2016 @Ally Dale. All rights reserved. 13 | // Author : Ally Dale(vipally@gmail.com) 14 | // Blog : http://blog.csdn.net/vipally 15 | // Site : https://github.com/vipally 16 | // BuildAt : 17 | // Version : 3.0.0.final 18 | // 19 | /////////////////////////////////////////////////////////////////// 20 | 21 | package stl 22 | 23 | //////////////////////////////////////////////////////////////////////////////// 24 | 25 | type IntHeap struct { 26 | b []int //data buffer 27 | limitN int //if limitN>0, heap size must<=limitN 28 | cmp CmpInt //if top is max value 29 | } 30 | 31 | //new object 32 | func NewIntHeap(capacity, limitN int, maxTop bool) (r *IntHeap) { 33 | r = &IntHeap{} 34 | r.Init(capacity, limitN, maxTop) 35 | return 36 | } 37 | 38 | //initialize 39 | func (this *IntHeap) Init(capacity, limitN int, maxTop bool) { 40 | if cap(this.b) < capacity { 41 | this.b = make([]int, 0, capacity) 42 | } 43 | this.b = this.b[:0] 44 | 45 | this.limitN = limitN 46 | this.cmp = this.cmp.CreateByBool(!maxTop) 47 | } 48 | 49 | //push heap value 50 | func (this *IntHeap) PushHeap(b []int, v int) []int { 51 | b = append(b, v) 52 | this.adjustUp(b, len(b)-1, v) 53 | return b 54 | } 55 | 56 | //pop heap top 57 | func (this *IntHeap) PopHeap(b []int) (h []int, top int, ok bool) { 58 | l := len(b) 59 | if ok = l > 0; ok { 60 | top = b[0] 61 | if l > 1 { 62 | b[0], b[l-1] = b[l-1], b[0] 63 | this.adjustDown(b[:l-1], 0, b[0]) 64 | } 65 | h = b[:l-1] 66 | } 67 | return 68 | } 69 | 70 | //check if b is a valid heap 71 | func (this *IntHeap) CheckHeap(b []int) bool { 72 | for i := len(b) - 1; i > 0; i-- { 73 | p := this.parent(i) 74 | if !this.cmpV(b[i], b[p]) { 75 | return false 76 | } 77 | } 78 | return true 79 | } 80 | 81 | //adjust heap to select a proper hole to set v 82 | func (this *IntHeap) adjustDown(b []int, hole int, v int) { 83 | size := len(b) 84 | 85 | //try to improve STL's adjust down algorithm 86 | //adjust heap to select a proper hole to set v 87 | for l := this.lchild(hole); l < size; l = this.lchild(hole) { 88 | c := l //index that need compare with hole 89 | if r := l + 1; r < size && !this.cmpV(b[r], b[l]) { //let the most proper child to compare with v 90 | c = r 91 | } 92 | if this.cmpV(b[c], v) { //v is the most proper root, finish adjust 93 | break 94 | } else { //c is the most proper root, swap with hole, and continue adjust 95 | b[hole], hole = b[c], c 96 | } 97 | } 98 | b[hole] = v //put v to last hole 99 | 100 | } 101 | 102 | //adjust heap to select a proper hole to set v 103 | func (this *IntHeap) adjustUp(b []int, hole int, v int) { 104 | for hole > 0 { 105 | if parent := this.parent(hole); !this.cmpV(v, b[parent]) { 106 | b[hole], hole = b[parent], parent 107 | } else { 108 | break 109 | } 110 | } 111 | b[hole] = v //put v to last hole 112 | } 113 | 114 | //make b as a heap 115 | func (this *IntHeap) MakeHeap(b []int) { 116 | if l := len(b); l > 1 { 117 | for i := l / 2; i >= 0; i-- { 118 | this.adjustDown(b, i, b[i]) 119 | } 120 | } 121 | } 122 | 123 | //reverse order of b 124 | func (this *IntHeap) Reverse(b []int) { 125 | l := len(b) - 1 126 | for i := l / 2; i >= 0; i-- { 127 | b[i], b[l-i] = b[l-i], b[i] 128 | } 129 | } 130 | 131 | //sort slice use heap algorithm 132 | func (this *IntHeap) SortHeap(b []int) []int { 133 | this.MakeHeap(b) 134 | for t := b; len(t) > 1; { 135 | t, _, _ = this.PopHeap(t) 136 | } 137 | return b 138 | } 139 | 140 | //heap slice 141 | func (this *IntHeap) Buffer() []int { 142 | return this.b 143 | } 144 | 145 | //push 146 | func (this *IntHeap) Push(v int) { 147 | if this.limitN > 0 && this.Size() >= this.limitN { 148 | if top, ok := this.Top(); ok && this.cmpV(v, top) { 149 | this.Pop() 150 | } else { 151 | return 152 | } 153 | } 154 | this.b = this.PushHeap(this.b, v) 155 | } 156 | 157 | //pop 158 | func (this *IntHeap) Pop() (top int, ok bool) { 159 | this.b, top, ok = this.PopHeap(this.b) 160 | return 161 | } 162 | 163 | //heap top 164 | func (this *IntHeap) Top() (top int, ok bool) { 165 | if ok = !this.Empty(); ok { 166 | top = this.b[0] 167 | } 168 | return 169 | } 170 | 171 | //cmpare value 172 | func (this *IntHeap) cmpV(c, p int) (ok bool) { 173 | ok = !this.cmp.F(p, c) 174 | return 175 | } 176 | 177 | //get parent index 178 | func (this *IntHeap) parent(idx int) int { 179 | return (idx - 1) / 2 180 | } 181 | 182 | //get left child index 183 | func (this *IntHeap) lchild(idx int) int { 184 | return 2*idx + 1 185 | } 186 | 187 | //get right child index 188 | //func (this *GOGPHeapNamePrefixHeap) rchild(idx int) int { 189 | // return 2*idx + 2 190 | //} 191 | 192 | //func (this *GOGPHeapNamePrefixHeap) children(idx int) (l, r int) { 193 | // l = 2*idx + 1 194 | // r = l + 1 195 | // return 196 | //} 197 | 198 | //size 199 | func (this *IntHeap) Size() int { 200 | return len(this.b) 201 | } 202 | 203 | //empty 204 | func (this *IntHeap) Empty() bool { 205 | return this.Size() == 0 206 | } 207 | -------------------------------------------------------------------------------- /stl/queue.gp_int.go: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // 3 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 4 | // 5 | // This file was auto-generated by tool [github.com/vipally/gogp] 6 | // Last update at: [Sat Apr 01 2017 22:48:09] 7 | // Generate from: 8 | // [github.com/vipally/gx/stl/gp/queue.gp] 9 | // [github.com/vipally/gx/stl/stl.gpg] [queue_int] 10 | // 11 | // Tool [github.com/vipally/gogp] info: 12 | // CopyRight 2016 @Ally Dale. All rights reserved. 13 | // Author : Ally Dale(vipally@gmail.com) 14 | // Blog : http://blog.csdn.net/vipally 15 | // Site : https://github.com/vipally 16 | // BuildAt : 17 | // Version : 3.0.0.final 18 | // 19 | /////////////////////////////////////////////////////////////////// 20 | 21 | package stl 22 | 23 | //////////////////////////////////////////////////////////////////////////////// 24 | 25 | //queue object 26 | type IntQueue struct { 27 | //real data is [head,tail) 28 | //buffer d is cycle, that is to say, next(len(d)-1)=0, prev(0)=len(d)-1 29 | //so if tail 0 { 57 | this.d = make([]int, bufSize, bufSize) //the same cap and len 58 | } 59 | } 60 | 61 | //clear 62 | func (this *IntQueue) Clear() { 63 | this.head, this.tail = 0, 0 64 | } 65 | 66 | //push to back of queue 67 | func (this *IntQueue) Push(v int) (ok bool) { 68 | if ok = true; ok { 69 | if nil == this.d { //init if needed 70 | this.Init(-1) 71 | } 72 | this.d[this.tail] = v 73 | if this.tail++; this.tail >= this.Cap() { 74 | this.tail = 0 75 | if this.tail == this.head { //tail catch up head, buffer full 76 | oldCap := this.Cap() 77 | d := this.d 78 | this.newBuf(oldCap * 2) 79 | h := copy(this.d, d[this.head:]) 80 | t := copy(this.d[:h], d[:this.tail]) 81 | this.head, this.tail = 0, h+t 82 | } 83 | } 84 | } 85 | return 86 | } 87 | 88 | //pop front of queue 89 | func (this *IntQueue) Pop() (front int, ok bool) { 90 | if ok = this.head != this.tail; ok { 91 | front = this.d[this.head] 92 | if this.head++; this.head >= this.Cap() && this.head != this.tail { 93 | this.head = 0 94 | } 95 | } 96 | return 97 | } 98 | 99 | //front data 100 | func (this *IntQueue) Front() (front int, ok bool) { 101 | if ok = this.head != this.tail; ok { 102 | front = this.d[this.head] 103 | } 104 | return 105 | } 106 | 107 | //back data 108 | func (this *IntQueue) Back() (back int, ok bool) { 109 | if ok = this.head != this.tail; ok { 110 | t := this.tail - 1 111 | if t < 0 { 112 | t = this.Cap() - 1 113 | } 114 | back = this.d[t] 115 | } 116 | return 117 | } 118 | 119 | //shrink data buffer if necessary 120 | func (this *IntQueue) Shrink() (ok bool) { 121 | oldCap := this.Cap() 122 | oldSize := this.Size() 123 | if ok := oldCap > 8 && oldCap >= 3*oldSize; ok { //leave at least 8 elem space 124 | d := this.d 125 | this.newBuf(oldSize / 2) 126 | if this.tail >= this.head { 127 | copy(this.d, d[this.head:this.tail]) 128 | this.tail -= this.head 129 | this.head = 0 130 | } else { 131 | h := copy(this.d, d[this.head:]) 132 | t := copy(this.d[:h], d[:this.tail]) 133 | this.head, this.tail = 0, h+t 134 | } 135 | } 136 | return 137 | } 138 | 139 | //func (this *GOGPDequeNamePrefixDeque) Sort() {} 140 | 141 | //data buffer size 142 | func (this *IntQueue) Cap() int { 143 | return len(this.d) 144 | } 145 | 146 | //size of queue 147 | func (this *IntQueue) Size() (size int) { 148 | if this.tail >= this.head { 149 | size = this.tail - this.head 150 | } else { 151 | size = this.Cap() - this.head + this.tail 152 | } 153 | return 154 | } 155 | 156 | //if queue is empty 157 | func (this *IntQueue) Empty() bool { 158 | return this.Size() == 0 159 | } 160 | 161 | ////show 162 | //func (this *GOGPQueueNamePrefixQueue) Show() string { 163 | // var b show_bytes.Buffer 164 | // b.WriteByte('[') 165 | // for i := this.head; i != this.tail; i++ { 166 | // if i >= this.Cap() { 167 | // i = 0 168 | // } 169 | // v = this.v[i] 170 | // b.WriteString(v.Show()) 171 | // b.WriteByte(',') 172 | // } 173 | // if this.Depth() > 0 { 174 | // b.Truncate(b.Len() - 1) //remove last ',' 175 | // } 176 | // b.WriteByte(']') 177 | // return b.String() 178 | //} 179 | -------------------------------------------------------------------------------- /stl/sort_slice.gp_#inttreenodeb60b.go: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // 3 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 4 | // 5 | // This file was auto-generated by tool [github.com/vipally/gogp] 6 | // Last update at: [Sat Apr 01 2017 22:48:09] 7 | // Generate from: 8 | // [github.com/vipally/gx/stl/gp/sort_slice.gp] 9 | // [github.com/vipally/gx/stl/stl.gpg] [_tree_sort_slice_int] 10 | // 11 | // Tool [github.com/vipally/gogp] info: 12 | // CopyRight 2016 @Ally Dale. All rights reserved. 13 | // Author : Ally Dale(vipally@gmail.com) 14 | // Blog : http://blog.csdn.net/vipally 15 | // Site : https://github.com/vipally 16 | // BuildAt : 17 | // Version : 3.0.0.final 18 | // 19 | /////////////////////////////////////////////////////////////////// 20 | 21 | //this file define a template type for sort 22 | 23 | package stl 24 | 25 | import "sort" 26 | 27 | //////////////////////////////////////////////////////////////////////////////// 28 | 29 | var gIntTreeNodeSortSliceGbl struct { 30 | cmp CmpIntTreeNode 31 | } 32 | 33 | func init() { 34 | gIntTreeNodeSortSliceGbl.cmp = gIntTreeNodeSortSliceGbl.cmp.CreateByName("") 35 | } 36 | 37 | //new sort object 38 | func NewIntTreeNodeSortSlice(capacity int) *IntTreeNodeSortSlice { 39 | p := &IntTreeNodeSortSlice{} 40 | p.Init(capacity) 41 | return p 42 | } 43 | 44 | //sort slice 45 | type IntTreeNodeSortSlice struct { 46 | d []*IntTreeNode 47 | } 48 | 49 | //init 50 | func (this *IntTreeNodeSortSlice) Init(capacity int) { 51 | this.d = make([]*IntTreeNode, 0, capacity) 52 | } 53 | 54 | //sort 55 | func (this *IntTreeNodeSortSlice) Sort() { 56 | sort.Sort(this) 57 | } 58 | 59 | //data buffer 60 | func (this *IntTreeNodeSortSlice) Buffer() []*IntTreeNode { 61 | return this.d 62 | } 63 | 64 | //push 65 | func (this *IntTreeNodeSortSlice) Push(v *IntTreeNode) int { 66 | this.d = append(this.d, v) 67 | return this.Len() 68 | } 69 | 70 | //insert 71 | func (this *IntTreeNodeSortSlice) Insert(v *IntTreeNode, idx int) int { 72 | if idx >= 0 && idx < this.Len() { 73 | right := this.d[idx+1:] 74 | this.d = append(this.d[:idx], v) 75 | this.d = append(this.d, right...) 76 | } else { 77 | this.d = append(this.d, v) 78 | } 79 | return this.Len() 80 | } 81 | 82 | //remove 83 | func (this *IntTreeNodeSortSlice) Remove(idx int) (r *IntTreeNode, ok bool) { 84 | if r, ok = this.Get(idx); ok { 85 | right := this.d[idx+1:] 86 | this.d = append(this.d[:idx], right...) 87 | } 88 | return 89 | } 90 | 91 | //pop 92 | func (this *IntTreeNodeSortSlice) Pop() (r *IntTreeNode, ok bool) { 93 | if ok = len(this.d) > 0; ok { 94 | r = (this.d)[len(this.d)-1] 95 | } 96 | this.d = (this.d)[:len(this.d)-1] 97 | return 98 | } 99 | 100 | //get 101 | func (this *IntTreeNodeSortSlice) Get(idx int) (r *IntTreeNode, ok bool) { 102 | if ok = idx >= 0 && idx < this.Len(); ok { 103 | r = this.d[idx] 104 | } 105 | return 106 | } 107 | 108 | //must get 109 | func (this *IntTreeNodeSortSlice) MustGet(idx int) (r *IntTreeNode) { 110 | ok := false 111 | if r, ok = this.Get(idx); !ok { 112 | panic(idx) 113 | } 114 | return 115 | } 116 | 117 | //len 118 | func (this *IntTreeNodeSortSlice) Len() int { 119 | return len(this.d) 120 | } 121 | 122 | //sort by Hash decend,the larger one first 123 | func (this *IntTreeNodeSortSlice) Less(i, j int) (ok bool) { 124 | l, r := (this.d)[i], (this.d)[j] 125 | return gIntTreeNodeSortSliceGbl.cmp.F(l, r) 126 | } 127 | 128 | //swap 129 | func (this *IntTreeNodeSortSlice) Swap(i, j int) { 130 | (this.d)[i], (this.d)[j] = (this.d)[j], (this.d)[i] 131 | } 132 | -------------------------------------------------------------------------------- /stl/sort_slice.gp_int.go: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // 3 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 4 | // 5 | // This file was auto-generated by tool [github.com/vipally/gogp] 6 | // Last update at: [Sat Apr 01 2017 22:48:09] 7 | // Generate from: 8 | // [github.com/vipally/gx/stl/gp/sort_slice.gp] 9 | // [github.com/vipally/gx/stl/stl.gpg] [sort_slice_int] 10 | // 11 | // Tool [github.com/vipally/gogp] info: 12 | // CopyRight 2016 @Ally Dale. All rights reserved. 13 | // Author : Ally Dale(vipally@gmail.com) 14 | // Blog : http://blog.csdn.net/vipally 15 | // Site : https://github.com/vipally 16 | // BuildAt : 17 | // Version : 3.0.0.final 18 | // 19 | /////////////////////////////////////////////////////////////////// 20 | 21 | //this file define a template type for sort 22 | 23 | package stl 24 | 25 | import "sort" 26 | 27 | //////////////////////////////////////////////////////////////////////////////// 28 | 29 | var gIntSortSliceGbl struct { 30 | cmp CmpInt 31 | } 32 | 33 | func init() { 34 | gIntSortSliceGbl.cmp = gIntSortSliceGbl.cmp.CreateByName("") 35 | } 36 | 37 | //new sort object 38 | func NewIntSortSlice(capacity int) *IntSortSlice { 39 | p := &IntSortSlice{} 40 | p.Init(capacity) 41 | return p 42 | } 43 | 44 | //sort slice 45 | type IntSortSlice struct { 46 | d []int 47 | } 48 | 49 | //init 50 | func (this *IntSortSlice) Init(capacity int) { 51 | this.d = make([]int, 0, capacity) 52 | } 53 | 54 | //sort 55 | func (this *IntSortSlice) Sort() { 56 | sort.Sort(this) 57 | } 58 | 59 | //data buffer 60 | func (this *IntSortSlice) Buffer() []int { 61 | return this.d 62 | } 63 | 64 | //push 65 | func (this *IntSortSlice) Push(v int) int { 66 | this.d = append(this.d, v) 67 | return this.Len() 68 | } 69 | 70 | //insert 71 | func (this *IntSortSlice) Insert(v int, idx int) int { 72 | if idx >= 0 && idx < this.Len() { 73 | right := this.d[idx+1:] 74 | this.d = append(this.d[:idx], v) 75 | this.d = append(this.d, right...) 76 | } else { 77 | this.d = append(this.d, v) 78 | } 79 | return this.Len() 80 | } 81 | 82 | //remove 83 | func (this *IntSortSlice) Remove(idx int) (r int, ok bool) { 84 | if r, ok = this.Get(idx); ok { 85 | right := this.d[idx+1:] 86 | this.d = append(this.d[:idx], right...) 87 | } 88 | return 89 | } 90 | 91 | //pop 92 | func (this *IntSortSlice) Pop() (r int, ok bool) { 93 | if ok = len(this.d) > 0; ok { 94 | r = (this.d)[len(this.d)-1] 95 | } 96 | this.d = (this.d)[:len(this.d)-1] 97 | return 98 | } 99 | 100 | //get 101 | func (this *IntSortSlice) Get(idx int) (r int, ok bool) { 102 | if ok = idx >= 0 && idx < this.Len(); ok { 103 | r = this.d[idx] 104 | } 105 | return 106 | } 107 | 108 | //must get 109 | func (this *IntSortSlice) MustGet(idx int) (r int) { 110 | ok := false 111 | if r, ok = this.Get(idx); !ok { 112 | panic(idx) 113 | } 114 | return 115 | } 116 | 117 | //len 118 | func (this *IntSortSlice) Len() int { 119 | return len(this.d) 120 | } 121 | 122 | //sort by Hash decend,the larger one first 123 | func (this *IntSortSlice) Less(i, j int) (ok bool) { 124 | l, r := (this.d)[i], (this.d)[j] 125 | return gIntSortSliceGbl.cmp.F(l, r) 126 | } 127 | 128 | //swap 129 | func (this *IntSortSlice) Swap(i, j int) { 130 | (this.d)[i], (this.d)[j] = (this.d)[j], (this.d)[i] 131 | } 132 | -------------------------------------------------------------------------------- /stl/stack.gp_int.go: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // 3 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 4 | // 5 | // This file was auto-generated by tool [github.com/vipally/gogp] 6 | // Last update at: [Sat Apr 01 2017 22:48:09] 7 | // Generate from: 8 | // [github.com/vipally/gx/stl/gp/stack.gp] 9 | // [github.com/vipally/gx/stl/stl.gpg] [stack_int] 10 | // 11 | // Tool [github.com/vipally/gogp] info: 12 | // CopyRight 2016 @Ally Dale. All rights reserved. 13 | // Author : Ally Dale(vipally@gmail.com) 14 | // Blog : http://blog.csdn.net/vipally 15 | // Site : https://github.com/vipally 16 | // BuildAt : 17 | // Version : 3.0.0.final 18 | // 19 | /////////////////////////////////////////////////////////////////// 20 | 21 | package stl 22 | 23 | //////////////////////////////////////////////////////////////////////////////// 24 | 25 | //stack object 26 | type IntStack struct { 27 | d []int 28 | } 29 | 30 | //new object 31 | func NewGOGPStackNamePrefixStack(bufSize int) *IntStack { 32 | r := &IntStack{} 33 | r.Init(bufSize) 34 | return r 35 | } 36 | 37 | //init 38 | func (this *IntStack) Init(bufSize int) { 39 | if nil == this.d { 40 | if -1 == bufSize { 41 | bufSize = 10 42 | } 43 | if bufSize > 0 { 44 | this.d = make([]int, 0, bufSize) 45 | } 46 | } 47 | this.d = this.d[:0] 48 | return 49 | } 50 | 51 | //clear 52 | func (this *IntStack) Clear() { 53 | this.Init(-1) 54 | } 55 | 56 | //push v to top of stack 57 | func (this *IntStack) Push(v int) (ok bool) { 58 | if ok = true; ok { 59 | this.d = append(this.d, v) 60 | } 61 | return 62 | } 63 | 64 | //pop top of stack 65 | func (this *IntStack) Pop() (top int, ok bool) { 66 | if top, ok = this.Top(); ok { 67 | this.d = this.d[:this.Size()-1] 68 | } 69 | return 70 | } 71 | 72 | //get top of stack 73 | func (this *IntStack) Top() (top int, ok bool) { 74 | d := this.Size() 75 | if d > 0 { 76 | top = this.d[d-1] 77 | ok = true 78 | } 79 | return 80 | 81 | } 82 | 83 | //size of stack 84 | func (this *IntStack) Size() int { 85 | return len(this.d) 86 | } 87 | 88 | //is stack is empty 89 | func (this *IntStack) Empty() bool { 90 | return this.Size() == 0 91 | } 92 | 93 | ////show 94 | //func (this *IntStack) Show() string { 95 | // var b show_bytes.Buffer 96 | // b.WriteByte('[') 97 | // for _, v := range this.d { 98 | // b.WriteString(v.Show()) 99 | // b.WriteByte(',') 100 | // } 101 | // if this.Size() > 0 { 102 | // b.Truncate(b.Len() - 1) //remove last ',' 103 | // } 104 | // b.WriteByte(']') 105 | // return b.String() 106 | //} // 107 | -------------------------------------------------------------------------------- /stl/stl.gpg: -------------------------------------------------------------------------------- 1 | ;this is exactlly an ini file 2 | ;this is an example of gogp reverse usage: generate .gp file form .gpg and .go file, sectionname must be lead with GOGP_REVERSE 3 | ;other section is used to do the next thing, gen .go file from .gpg and .gp file 4 | 5 | [sort_slice_int] 6 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/sort_slice 7 | PACKAGE=package stl 8 | VALUE_TYPE=int 9 | GLOBAL_NAME_PREFIX=Int 10 | 11 | [tree_int] 12 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/tree 13 | GOGP_HasCmpFunc=false 14 | GOGP_SectionSortSlice=_tree_sort_slice_int 15 | PACKAGE=package stl 16 | VALUE_TYPE=int 17 | GLOBAL_NAME_PREFIX=Int 18 | 19 | [_tree_sort_slice_int] 20 | GOGP_Ignore=true 21 | ;GOGP_DontSave=true 22 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/sort_slice 23 | GOGP_HasCmpFunc=true 24 | PACKAGE=package stl 25 | VALUE_TYPE=*IntTreeNode 26 | GLOBAL_NAME_PREFIX=IntTreeNode 27 | 28 | [stack_int] 29 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/stack 30 | GOGP_HasShow=false 31 | PACKAGE=package stl 32 | VALUE_TYPE=int 33 | GLOBAL_NAME_PREFIX=Int 34 | 35 | [deque_int] 36 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/deque 37 | PACKAGE=package stl 38 | VALUE_TYPE=int 39 | GLOBAL_NAME_PREFIX=Int 40 | 41 | [queue_int] 42 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/queue 43 | PACKAGE=package stl 44 | VALUE_TYPE=int 45 | GLOBAL_NAME_PREFIX=Int 46 | 47 | [heap_int] 48 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/heap 49 | GOGP_ImproveSTL=true 50 | PACKAGE=package stl 51 | VALUE_TYPE=int 52 | GLOBAL_NAME_PREFIX=Int 53 | 54 | [list_int] 55 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/list 56 | PACKAGE=package stl 57 | VALUE_TYPE=int 58 | GLOBAL_NAME_PREFIX=Int 59 | 60 | [slist_int] 61 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/slist 62 | PACKAGE=package stl 63 | VALUE_TYPE=int 64 | GLOBAL_NAME_PREFIX=Int 65 | 66 | 67 | 68 | [bstree_int] 69 | GOGP_Ignore=true 70 | GOGP_GpFilePath=github.com/vipally/gx/stl/gp/bstree 71 | GOGP_HasKeyType=true 72 | PACKAGE=package stl 73 | KEY_TYPE=GOGPKeyType 74 | VALUE_TYPE=int 75 | GLOBAL_NAME_PREFIX=Int 76 | -------------------------------------------------------------------------------- /stl/stl_test.go: -------------------------------------------------------------------------------- 1 | package stl 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | //"time" 7 | //"regexp" 8 | 9 | //_ "github.com/vipally/gogp/auto" 10 | ) 11 | 12 | func init() { 13 | // s := []GOGPSliceElem{6, 7, 8, 3, 4, 6} 14 | // //MakeSlice(s).Sort() 15 | // ss := GOGPTreeNamePrefixSortSlice(s) 16 | // ss.Sort() 17 | // ss.Pop() 18 | // for _, v := range ss.D() { 19 | // fmt.Println(v) 20 | // } 21 | } 22 | 23 | func TestHeap(t *testing.T) { 24 | a := []int{4, 5, 6, 2, 9, 8, 4, 7} 25 | h := NewIntHeap(0, 6, false) 26 | for _, v := range a { 27 | h.Push(v) 28 | } 29 | for !h.Empty() { 30 | v, _ := h.Pop() 31 | fmt.Printf("%d ", v) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /stl/tree.gp_int.go: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////// 2 | // 3 | // !!!!!!!!!!!! NEVER MODIFY THIS FILE MANUALLY !!!!!!!!!!!! 4 | // 5 | // This file was auto-generated by tool [github.com/vipally/gogp] 6 | // Last update at: [Sat Apr 01 2017 22:48:09] 7 | // Generate from: 8 | // [github.com/vipally/gx/stl/gp/tree.gp] 9 | // [github.com/vipally/gx/stl/stl.gpg] [tree_int] 10 | // 11 | // Tool [github.com/vipally/gogp] info: 12 | // CopyRight 2016 @Ally Dale. All rights reserved. 13 | // Author : Ally Dale(vipally@gmail.com) 14 | // Blog : http://blog.csdn.net/vipally 15 | // Site : https://github.com/vipally 16 | // BuildAt : 17 | // Version : 3.0.0.final 18 | // 19 | /////////////////////////////////////////////////////////////////// 20 | 21 | //this file defines a template tree structure just like file system 22 | 23 | package stl 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | 27 | //tree strture 28 | type IntTree struct { 29 | root *IntTreeNode 30 | } 31 | 32 | //new container 33 | func NewIntTree() *IntTree { 34 | p := &IntTree{} 35 | return p 36 | } 37 | 38 | //tree node 39 | type IntTreeNode struct { 40 | val int 41 | children IntTreeNodeSortSlice 42 | } 43 | 44 | func (this *IntTreeNode) Less(right *IntTreeNode) (ok bool) { 45 | 46 | ok = this.val < right.val 47 | 48 | return 49 | } 50 | 51 | func (this *IntTreeNode) SortChildren() { 52 | this.children.Sort() 53 | } 54 | 55 | func (this *IntTreeNode) Children() []*IntTreeNode { 56 | return this.children.Buffer() 57 | } 58 | 59 | //add a child 60 | func (this *IntTreeNode) AddChild(v int, idx int) (child *IntTreeNode) { 61 | n := &IntTreeNode{val: v} 62 | return this.AddChildNode(n, idx) 63 | } 64 | 65 | //add a child node 66 | func (this *IntTreeNode) AddChildNode(node *IntTreeNode, idx int) (child *IntTreeNode) { 67 | this.children.Insert(node, idx) 68 | return node 69 | } 70 | 71 | //cound of children 72 | func (this *IntTreeNode) NumChildren() int { 73 | return this.children.Len() 74 | } 75 | 76 | //get child 77 | func (this *IntTreeNode) GetChild(idx int) (child *IntTreeNode, ok bool) { 78 | child, ok = this.children.Get(idx) 79 | return 80 | } 81 | 82 | //remove child 83 | func (this *IntTreeNode) RemoveChild(idx int) (child *IntTreeNode, ok bool) { 84 | child, ok = this.children.Remove(idx) 85 | return 86 | } 87 | 88 | //create a visitor 89 | func (this *IntTreeNode) Visitor() (v *IntTreeNodeVisitor) { 90 | v = &IntTreeNodeVisitor{} 91 | v.push(this, -1) 92 | return 93 | } 94 | 95 | //get all node data 96 | func (this *IntTreeNode) All() (list []int) { 97 | list = append(list, this.val) 98 | for _, v := range this.children.Buffer() { 99 | list = append(list, v.All()...) 100 | } 101 | return 102 | } 103 | 104 | //tree node visitor 105 | type IntTreeNodeVisitor struct { 106 | node *IntTreeNode 107 | parents []*IntTreeNode 108 | brotherIdxes []int 109 | //visit order: this->child->brother 110 | } 111 | 112 | func (this *IntTreeNodeVisitor) push(n *IntTreeNode, bIdx int) { 113 | this.parents = append(this.parents, n) 114 | this.brotherIdxes = append(this.brotherIdxes, bIdx) 115 | } 116 | 117 | func (this *IntTreeNodeVisitor) pop() (n *IntTreeNode, bIdx int) { 118 | l := len(this.parents) 119 | if l > 0 { 120 | n, bIdx = this.tail() 121 | this.parents = this.parents[:l-1] 122 | this.brotherIdxes = this.brotherIdxes[:l-1] 123 | } 124 | return 125 | } 126 | 127 | func (this *IntTreeNodeVisitor) tail() (n *IntTreeNode, bIdx int) { 128 | l := len(this.parents) 129 | if l > 0 { 130 | n = this.parents[l-1] 131 | bIdx = this.brotherIdxes[l-1] 132 | } 133 | return 134 | } 135 | 136 | func (this *IntTreeNodeVisitor) depth() int { 137 | return len(this.parents) 138 | } 139 | 140 | func (this *IntTreeNodeVisitor) update_tail(bIdx int) bool { 141 | l := len(this.parents) 142 | if l > 0 { 143 | this.brotherIdxes[l-1] = bIdx 144 | return true 145 | } 146 | return false 147 | } 148 | 149 | func (this *IntTreeNodeVisitor) top_right(n *IntTreeNode) (p *IntTreeNode) { 150 | if n != nil { 151 | l := n.children.Len() 152 | for l > 0 { 153 | this.push(n, l-1) 154 | n = n.children.MustGet(l - 1) 155 | l = n.children.Len() 156 | } 157 | p = n 158 | } 159 | return 160 | } 161 | 162 | //visit next node 163 | func (this *IntTreeNodeVisitor) Next() (ok bool) { 164 | if this.node != nil { //check if has any children 165 | if this.node.children.Len() > 0 { 166 | this.push(this.node, 0) 167 | this.node = this.node.children.MustGet(0) 168 | } else { 169 | this.node = nil 170 | } 171 | } 172 | for this.node == nil && this.depth() > 0 { //check if has any brothers or uncles 173 | p, bIdx := this.tail() 174 | if bIdx < 0 { //ref parent 175 | this.node = p 176 | this.pop() 177 | } else if bIdx < p.children.Len()-1 { //next brother 178 | bIdx++ 179 | this.node = p.children.MustGet(bIdx) 180 | this.update_tail(bIdx) 181 | } else { //no more brothers 182 | this.pop() 183 | } 184 | } 185 | if ok = this.node != nil; ok { 186 | //do nothing 187 | } 188 | return 189 | } 190 | 191 | //visit previous node 192 | func (this *IntTreeNodeVisitor) Prev() (ok bool) { 193 | if this.node == nil && this.depth() > 0 { //check if has any brothers or uncles 194 | p, _ := this.pop() 195 | this.node = this.top_right(p) 196 | if ok = this.node != nil; ok { 197 | //do nothing 198 | } 199 | return 200 | } 201 | 202 | if this.node != nil { //check if has any children 203 | p, bIdx := this.tail() 204 | if bIdx > 0 { 205 | bIdx-- 206 | this.update_tail(bIdx) 207 | this.node = this.top_right(p.children.MustGet(bIdx)) 208 | } else { 209 | this.node = p 210 | this.pop() 211 | } 212 | } 213 | if ok = this.node != nil; ok { 214 | //do nothing 215 | } 216 | return 217 | } 218 | 219 | //get node data 220 | func (this *IntTreeNodeVisitor) Get() (data int) { 221 | if nil != this.node { 222 | data = this.node.val 223 | } 224 | return 225 | } 226 | -------------------------------------------------------------------------------- /strings/rand.go: -------------------------------------------------------------------------------- 1 | package strings 2 | 3 | import ( 4 | xrand "github.com/vipally/gx/math/rand" 5 | ) 6 | 7 | var ( 8 | rnd = xrand.NewRand32() 9 | ) 10 | 11 | //rule of string 12 | type Rule uint 13 | 14 | const ( 15 | RULE_LIMIT_LEN Rule = 1 << (iota + 16) 16 | RULE_NUMBER 17 | RULE_LETTER 18 | RULE_LETTER_UPPER 19 | RULE_LETTER_LOWER 20 | RULE_SYMBOL 21 | 22 | RULE_NORMAL = RULE_NUMBER | RULE_LETTER 23 | RULE_STRONG = Rule(10) | RULE_NUMBER | RULE_LETTER_UPPER | RULE_LETTER_LOWER | RULE_SYMBOL 24 | RULE_NONE Rule = 0 25 | 26 | upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 27 | lower = "abcdefghijklmnopqrstuvwxyz" 28 | number = "1234567890" 29 | sign = "_-#@!$$&*[]{}<>?/\\~" 30 | ) 31 | 32 | //Generate a rand string with gived rule and length 33 | func Rand(rule Rule, length int) string { 34 | b := make([]byte, length, length) 35 | for i := 0; i < length; i++ { 36 | b[i] = upper[rnd.RandMax(uint32(len(upper)))] 37 | } 38 | return string(b) 39 | } 40 | 41 | //get rule of a string 42 | func GetRule(str string) Rule { 43 | return RULE_NONE 44 | } 45 | -------------------------------------------------------------------------------- /strings/rand_test.go: -------------------------------------------------------------------------------- 1 | package strings 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "testing" 7 | ) 8 | 9 | func TestRand(t *testing.T) { 10 | //rnd.Srand(10) 11 | for i := 0; i < 5; i++ { 12 | fmt.Println(Rand(RULE_STRONG, 8)) 13 | } 14 | fmt.Println(os.Getwd()) 15 | } 16 | -------------------------------------------------------------------------------- /sync/filelock/mutex.go: -------------------------------------------------------------------------------- 1 | package filelock 2 | 3 | import ( 4 | "sync" 5 | "syscall" 6 | "time" 7 | ) 8 | 9 | type Mutex struct { 10 | w sync.Mutex 11 | h syscall.Handle 12 | path string 13 | } 14 | 15 | func (this *Mutex) Init(path string) (ok bool) { 16 | this.w.Lock() 17 | defer this.w.Unlock() 18 | if this.path == "" { 19 | this.path = path 20 | ok = true 21 | } 22 | return 23 | } 24 | 25 | func (this *Mutex) Lock() (err error) { 26 | this.w.Lock() 27 | defer this.w.Unlock() 28 | for { 29 | h, e := syscall.CreateFile(syscall.StringToUTF16Ptr(this.path), 30 | syscall.GENERIC_READ|syscall.GENERIC_WRITE, 31 | 0, 32 | nil, 33 | syscall.OPEN_EXISTING, 34 | syscall.FILE_ATTRIBUTE_NORMAL|syscall.FILE_FLAG_OVERLAPPED, 35 | 0) 36 | if e == nil { 37 | this.h = h 38 | return 39 | } else if e != syscall.EACCES { 40 | return e 41 | } 42 | time.Sleep(time.Minute) //check every minute 43 | } 44 | 45 | } 46 | 47 | func (this *Mutex) Unlock() { 48 | this.w.Lock() 49 | defer this.w.Unlock() 50 | syscall.CloseHandle(this.h) 51 | this.h = 0 52 | 53 | } 54 | -------------------------------------------------------------------------------- /sync/filelock/rwmutex.go: -------------------------------------------------------------------------------- 1 | package filelock 2 | 3 | //lock using mmap file 4 | type RWMutex struct { 5 | w Mutex 6 | } 7 | 8 | func (this *RWMutex) Lock(path string) { 9 | 10 | } 11 | 12 | func (this *RWMutex) Unlock() { 13 | 14 | } 15 | 16 | func (this *RWMutex) RLock(path string) { 17 | 18 | } 19 | 20 | func (this *RWMutex) RUnlock() { 21 | 22 | } 23 | -------------------------------------------------------------------------------- /sync/lockfree/doc.go: -------------------------------------------------------------------------------- 1 | //package lockfree supply lockfree oprations and containers for goroutines share data but much care efficiency 2 | package lockfree 3 | -------------------------------------------------------------------------------- /sync/spinlock.go: -------------------------------------------------------------------------------- 1 | package sync 2 | 3 | import ( 4 | "sync" 5 | "sync/atomic" 6 | ) 7 | 8 | type Locker sync.Locker 9 | 10 | const ( 11 | spinLockLocked = 1 << iota 12 | 13 | spinLockMaxLoop = 1 << 24 //max spin times, to avoid dead lock 14 | ) 15 | 16 | type SpinLock struct { 17 | state int32 18 | } 19 | 20 | func (this *SpinLock) Lock() { 21 | for i := 0; ; i++ { 22 | if i > spinLockMaxLoop { 23 | panic("[sync] maybe dead lock on SpinLock") 24 | } 25 | 26 | if atomic.CompareAndSwapInt32(&this.state, 0, spinLockLocked) { 27 | break 28 | } 29 | } 30 | } 31 | func (this *SpinLock) Unlock() { 32 | if !atomic.CompareAndSwapInt32(&this.state, spinLockLocked, 0) { 33 | panic("[sync] Unlock on unlocked SpinLock") 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /sync/spinrwlock.go: -------------------------------------------------------------------------------- 1 | package sync 2 | 3 | import ( 4 | "sync/atomic" 5 | ) 6 | 7 | const ( 8 | rwSpinLockMaxReaders = 1 << 30 9 | ) 10 | 11 | type RWSpinLock struct { 12 | w SpinLock 13 | readerCount int32 14 | //readerWait int32 15 | } 16 | 17 | func (this *RWSpinLock) Lock() { 18 | this.w.Lock() //get writer lock first 19 | atomic.AddInt32(&this.readerCount, -rwSpinLockMaxReaders) //tell readers there is a writer 20 | } 21 | 22 | func (this *RWSpinLock) Unlock() { 23 | if r := atomic.AddInt32(&this.readerCount, rwSpinLockMaxReaders); r >= rwSpinLockMaxReaders { 24 | panic("[sync] Unlock on unlocked RWSpinLock") 25 | } 26 | this.w.Unlock() 27 | } 28 | 29 | func (this *RWSpinLock) RLock() { 30 | for i := 0; ; i++ { 31 | if i > spinLockMaxLoop { 32 | panic("[sync] maybe dead lock on RWSpinLock.RLock") 33 | } 34 | 35 | if r := atomic.LoadInt32(&this.readerCount); r >= 0 { // A writer is pending, wait for it. 36 | if atomic.AddInt32(&this.readerCount, 1) == 1 { 37 | this.w.Lock() //first waiter reader, block writer 38 | } 39 | break 40 | } 41 | } 42 | } 43 | func (this *RWSpinLock) RUnlock() { 44 | if r := atomic.AddInt32(&this.readerCount, -1); r < 0 { 45 | if r+1 == 0 || r+1 == -rwSpinLockMaxReaders { 46 | panic("sync: RUnlock of unlocked RWSpinLock") 47 | } 48 | if r == 0 { 49 | // The last reader unblocks the writer. 50 | this.w.Unlock() 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tasks/interface.go: -------------------------------------------------------------------------------- 1 | package tasks 2 | 3 | type Executer interface { 4 | Execute() bool 5 | } 6 | -------------------------------------------------------------------------------- /tasks/task_sys.go: -------------------------------------------------------------------------------- 1 | package tasks 2 | 3 | import ( 4 | "github.com/vipally/gx/time" 5 | ) 6 | 7 | var taskSys struct { 8 | run bool 9 | ch chan bool 10 | } 11 | 12 | type TaskSysStatus struct { 13 | Runing bool 14 | WaitingFinish bool 15 | CurWorkers int 16 | MaxWorkers int 17 | MaxListLen int 18 | TooBusyCount uint64 19 | FinishTaskCount uint64 20 | FreeTime time.Duration 21 | BusyTime time.Duration 22 | 23 | //caculate values 24 | AvgWorkers float32 25 | AvgListLen float32 26 | TotalTime time.Duration 27 | } 28 | 29 | func Start() { 30 | 31 | } 32 | 33 | func Stop() { 34 | 35 | } 36 | 37 | func PushTask() { 38 | 39 | } 40 | 41 | func workerFunc() {} 42 | -------------------------------------------------------------------------------- /tasks/time_wheel.go: -------------------------------------------------------------------------------- 1 | package tasks 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | const defaultTick = time.Second 8 | 9 | type TimeWheel struct { 10 | tick time.Duration 11 | } 12 | 13 | func NewDefaultTimeWheel() *TimeWheel { 14 | return NewTimeWheel(0) 15 | } 16 | 17 | func NewTimeWheel(tick time.Duration) *TimeWheel { 18 | if tick <= 0 { 19 | tick = defaultTick 20 | } 21 | return &TimeWheel{tick: tick} 22 | } 23 | -------------------------------------------------------------------------------- /time/duration.go: -------------------------------------------------------------------------------- 1 | // to extend std.time.Duration 2 | // and hide std.time for clients 3 | 4 | //packge time expand std.time and hide std.time depend for client 5 | package time 6 | 7 | import ( 8 | "fmt" 9 | "time" 10 | ) 11 | 12 | // compile error: cannot define new methods on non-local type time.Duration 13 | //func (d time.Duration) Days() float64 { 14 | // return float64(d) / float64(Day) 15 | //} 16 | 17 | //Duration is expand type for time.Duration 18 | type Duration time.Duration 19 | 20 | const ( 21 | Day = 24 * Hour //expand const 22 | Week = 7 * Day //expand const 23 | 24 | //////////////////////////////////////////////////////// 25 | //re-export std.Duration.consts 26 | //THIS LOOKS A LITTLE UGLY 27 | 28 | Nanosecond Duration = Duration(time.Nanosecond) 29 | Microsecond = Duration(time.Microsecond) 30 | Millisecond = Duration(time.Millisecond) 31 | Second = Duration(time.Second) 32 | Minute = Duration(time.Minute) 33 | Hour = Duration(time.Hour) 34 | //////////////////////////////////////////////////////// 35 | ) 36 | 37 | //std 38 | func (d Duration) Std() time.Duration { 39 | return time.Duration(d) 40 | } 41 | 42 | //expand method 43 | func (d Duration) Days() float64 { 44 | return float64(d) / float64(Day) 45 | } 46 | 47 | //expand method 48 | func (d Duration) Weeks() float64 { 49 | return float64(d) / float64(Week) 50 | } 51 | 52 | //expand std.Duration.String 53 | func (d Duration) String() string { 54 | if d < Day { 55 | return d.Std().String() 56 | } else { 57 | days := int(d / Day) 58 | left := d % Day 59 | return fmt.Sprintf("%dd%s", days, left.Std().String()) 60 | } 61 | return "" 62 | } 63 | 64 | //////////////////////////////////////////////////////// 65 | //re-export std.Duration.methods 66 | //THIS LOOKS A LITTLE UGLY 67 | 68 | //re-export std.Duration.Seconds 69 | func (d Duration) Seconds() float64 { 70 | return d.Std().Seconds() 71 | } 72 | 73 | //re-export std.Duration.Minutes 74 | func (d Duration) Minutes() float64 { 75 | return d.Std().Minutes() 76 | } 77 | 78 | //re-export std.Duration.Hours 79 | func (d Duration) Hours() float64 { 80 | return d.Std().Hours() 81 | } 82 | 83 | //re-export std.time.ParseDuration 84 | func ParseDuration(s string) (Duration, error) { 85 | d, err := time.ParseDuration(s) 86 | return Duration(d), err 87 | } 88 | 89 | //re-export std.time.Since 90 | func Since(t time.Time) Duration { 91 | return Duration(time.Since(t)) 92 | } 93 | 94 | //////////////////////////////////////////////////////// 95 | -------------------------------------------------------------------------------- /time/duration_test.go: -------------------------------------------------------------------------------- 1 | package time_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "time" //github.com/vipally/gx/time" 8 | 9 | xtime "github.com/vipally/gx/time" 10 | ) 11 | 12 | func TestStdDuration(t *testing.T) { 13 | var d time.Duration = time.Hour*25 + time.Minute 14 | fmt.Printf("DurationValue:%d, String:%s, Hours:%f\n", 15 | int64(d), d, d.Hours()) 16 | 17 | //import("github.com/vipally/gx/time"): 18 | // DurationValue:90060000000000, String:1d1h1m0s, Hours:25.016667 19 | 20 | //import("time"): 21 | // DurationValue:90060000000000, String:25h1m0s, Hours:25.016667 22 | } 23 | 24 | func TestDuration(t *testing.T) { 25 | var ds = []xtime.Duration{xtime.Day + xtime.Hour*12, xtime.Hour*12 + xtime.Minute} 26 | for _, d := range ds { 27 | fmt.Printf("DurationValue:%d, std:%s, expand:%s, Days:%f, Hours:%f\n", 28 | int64(d), d.Std(), d, d.Days(), d.Hours()) 29 | } 30 | 31 | //DurationValue:129600000000000, std:36h0m0s, expand:1d12h0m0s, Days:1.500000, Hours:36.000000 32 | //DurationValue:43260000000000, std:12h1m0s, expand:12h1m0s, Days:0.500694, Hours:12.016667 33 | } 34 | -------------------------------------------------------------------------------- /time/rdtsc.go: -------------------------------------------------------------------------------- 1 | // export some C time function such as RDTSC() from cgo 2 | 3 | package time 4 | 5 | /* 6 | #include 7 | unsigned long long rdtsc(void) 8 | { 9 | unsigned long long ullCPUTick = 0; 10 | __asm__ __volatile__("rdtsc" : "=A" (ullCPUTick) : ); 11 | return ullCPUTick; 12 | } 13 | */ 14 | import "C" 15 | 16 | //call rdtsc from C 17 | func RDTSC() uint64 { 18 | return uint64(C.rdtsc()) 19 | } 20 | 21 | //call clock() from C 22 | func Clock() uint64 { 23 | return uint64(C.clock()) 24 | } 25 | -------------------------------------------------------------------------------- /time/stopwatch/example_test.go: -------------------------------------------------------------------------------- 1 | package stopwatch_test 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "github.com/gxlb/gx/time/stopwatch" 8 | ) 9 | 10 | func ExampleSingle() { 11 | sw := stopwatch.NewSingle(stopwatch.WithUnit(time.Millisecond * 10)) 12 | time.Sleep(time.Second) 13 | d1 := sw.Duration() 14 | time.Sleep(time.Second) 15 | d2 := sw.Restart() 16 | time.Sleep(time.Second) 17 | d3 := sw.Duration() 18 | fmt.Printf("d1=%s\nd2=%s\nd3=%s", d1, d2, d3) 19 | 20 | // Output: 21 | // d1=1s 22 | // d2=2s 23 | // d3=1s 24 | } 25 | 26 | func ExampleStopWatch() { 27 | sw := stopwatch.New(stopwatch.WithStepCacheCap(5), 28 | stopwatch.WithUnit(stopwatch.Millisecond*10), 29 | stopwatch.WithName("stat")) 30 | for i := 0; i < 5; i++ { 31 | time.Sleep(time.Millisecond * time.Duration(100*(i+1))) 32 | sw.AddStepWatch(fmt.Sprintf("step%d", i+1), (i-2)*2) 33 | } 34 | fmt.Println(sw.ReportAll()) 35 | time.Sleep(time.Second) 36 | fmt.Println(sw.ReportOnce("final", 0)) 37 | 38 | // Output: 39 | // StopWatch(stat): 40 | // i=1 n=step1 t=100ms s=100ms 41 | // i=2 n=step2 t=300ms s=200ms 42 | // i=3 n=step3 t=600ms s=300ms 43 | // i=4 n=step4 t=1s s=400ms u(2)=200ms 44 | // i=5 n=step5 t=1.5s s=500ms u(4)=125ms 45 | // n=final t=2.5s s=1s 46 | } 47 | -------------------------------------------------------------------------------- /time/stopwatch/options.go: -------------------------------------------------------------------------------- 1 | package stopwatch 2 | 3 | // Option is the optional function. 4 | type Option func(opts *Options) 5 | 6 | func loadOptions(options ...Option) *Options { 7 | opts := new(Options) 8 | for _, option := range options { 9 | option(opts) 10 | } 11 | return opts 12 | } 13 | 14 | // Options contains all options which will be applied when instantiating a stopwatch. 15 | type Options struct { 16 | // StepCacheCap is the initial cap of step duration list. 17 | StepCacheCap int 18 | 19 | // Unit is the min time unit of duration report. 20 | Unit Duration 21 | 22 | // Name if name the the stop watch. 23 | Name string 24 | } 25 | 26 | // WithStepCacheCap is the optional function that set the initial cap of step cache. 27 | func WithStepCacheCap(stepCacheCap int) Option { 28 | return func(opts *Options) { 29 | opts.StepCacheCap = stepCacheCap 30 | } 31 | } 32 | 33 | // WithUnit is the optional function that set time unit of stopwatch. 34 | func WithUnit(unit Duration) Option { 35 | return func(opts *Options) { 36 | opts.Unit = unit 37 | } 38 | } 39 | 40 | // WithName is the optional function that set name of stopwatch. 41 | func WithName(name string) Option { 42 | return func(opts *Options) { 43 | opts.Name = name 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /time/stopwatch/single.go: -------------------------------------------------------------------------------- 1 | package stopwatch 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // NewSingle create a Single stopwatch 8 | func NewSingle(options ...Option) *Single { 9 | opts := loadOptions(options...) 10 | p := &Single{ 11 | startTime: time.Now(), 12 | unit: opts.Unit, 13 | } 14 | return p 15 | } 16 | 17 | // Single is a simple stopwatch that can only measure once. 18 | type Single struct { 19 | unit Duration 20 | startTime time.Time 21 | } 22 | 23 | // StartTime return start time of this stopwatch. 24 | func (w *Single) StartTime() time.Time { 25 | return w.startTime 26 | } 27 | 28 | // Start reset start time of this stopwatch. 29 | func (w *Single) Start() time.Time { 30 | w.startTime = time.Now() 31 | return w.StartTime() 32 | } 33 | 34 | func (w *Single) duration(reset bool) time.Duration { 35 | t := time.Now() 36 | dur := TrimDuration(t.Sub(w.startTime), w.unit) 37 | if reset { 38 | w.startTime = t 39 | } 40 | return dur 41 | } 42 | 43 | // Restart reset the start time and return duration since last start time. 44 | func (w *Single) Restart() Duration { 45 | return w.duration(true) 46 | } 47 | 48 | // Duration return duration since start time. 49 | func (w *Single) Duration() Duration { 50 | return w.duration(false) 51 | } 52 | 53 | // TrimDuration scale duration to boundary of time unit. 54 | func TrimDuration(dur Duration, unit Duration) Duration { 55 | if unit > 0 { 56 | dur += unit / 2 57 | return dur - dur%unit 58 | } 59 | return dur 60 | } 61 | -------------------------------------------------------------------------------- /time/stopwatch/stopwatch.go: -------------------------------------------------------------------------------- 1 | //Package stopwatch implements some easy way to mesure time 2 | package stopwatch 3 | 4 | import ( 5 | "bytes" 6 | "fmt" 7 | "time" 8 | ) 9 | 10 | // Duration alias time.Duration 11 | type Duration = time.Duration 12 | 13 | // Duration exports 14 | const ( 15 | Day = 24 * Hour //expand const 16 | Week = 7 * Day //expand const 17 | 18 | Nanosecond Duration = Duration(time.Nanosecond) 19 | Microsecond = Duration(time.Microsecond) 20 | Millisecond = Duration(time.Millisecond) 21 | Second = Duration(time.Second) 22 | Minute = Duration(time.Minute) 23 | Hour = Duration(time.Hour) 24 | ) 25 | 26 | // New create a new StopWatch. 27 | func New(options ...Option) *StopWatch { 28 | opts := loadOptions(options...) 29 | p := &StopWatch{ 30 | name: opts.Name, 31 | startTime: time.Now(), 32 | lastDur: 0, 33 | unit: opts.Unit, 34 | } 35 | if opts.StepCacheCap > 0 { 36 | p.durList = make([]WatchDuration, 0, opts.StepCacheCap) 37 | } 38 | 39 | return p 40 | } 41 | 42 | //StopWatch is a useful time mesure tool object 43 | type StopWatch struct { 44 | name string 45 | startTime time.Time 46 | lastDur Duration //last watch duration 47 | durList []WatchDuration 48 | unit Duration 49 | } 50 | 51 | // Start reset the start time. 52 | func (w *StopWatch) Start() time.Time { 53 | w.startTime = time.Now() 54 | w.durList = w.durList[:0] 55 | w.lastDur = 0 56 | return w.startTime 57 | } 58 | 59 | // Stop is alias of Restart 60 | func (w *StopWatch) Stop() Duration { 61 | return w.Restart() 62 | } 63 | 64 | func (w *StopWatch) duration(reset bool) Duration { 65 | t := time.Now() 66 | dur := TrimDuration(t.Sub(w.startTime), w.unit) 67 | if reset { 68 | w.startTime = t 69 | } 70 | return dur 71 | } 72 | 73 | // Restart restart the stop watch and return time duration from last start time 74 | func (w *StopWatch) Restart() Duration { 75 | d := w.duration(true) 76 | w.durList = w.durList[:0] 77 | w.lastDur = 0 78 | return d 79 | } 80 | 81 | // Clean reset the watch list but not reset the start time. 82 | func (w *StopWatch) Clean() Duration { 83 | d := w.duration(false) 84 | w.durList = w.durList[:0] 85 | w.lastDur = 0 86 | return d 87 | } 88 | 89 | // AddStepWatch add a new step watch with given name. 90 | // batchNum is used to report atomic time for batch testing. 91 | func (w *StopWatch) AddStepWatch(name string, batchNum int) WatchDuration { 92 | var d WatchDuration 93 | d.Init(name, w.duration(false), batchNum) 94 | 95 | w.lastDur = d.dur 96 | w.durList = append(w.durList, d) 97 | 98 | return d 99 | } 100 | 101 | // ReportOnce report duration as string. 102 | func (w *StopWatch) ReportOnce(name string, batchNum int) string { 103 | var d WatchDuration 104 | d.Init(name, w.duration(false), batchNum) 105 | 106 | return d.Report(-1, w.lastDur) 107 | } 108 | 109 | // ReportAll report all step watch as string. 110 | func (w *StopWatch) ReportAll() string { 111 | var buf bytes.Buffer 112 | buf.WriteString(fmt.Sprintf("StopWatch(%s):\n", w.name)) 113 | if nil != w.durList { 114 | lastDur := Duration(0) 115 | for i, v := range w.durList { 116 | if i > 0 { 117 | buf.WriteString("\n") 118 | } 119 | buf.WriteString(v.Report(i+1, lastDur)) 120 | 121 | lastDur = v.dur 122 | } 123 | } 124 | 125 | return buf.String() 126 | } 127 | 128 | // Count return number of steps reported. 129 | func (w *StopWatch) Count() int { 130 | return len(w.durList) 131 | } 132 | 133 | // TellDuration return duration from start time. 134 | func (w *StopWatch) TellDuration() Duration { 135 | dur := w.duration(false) 136 | return dur 137 | } 138 | 139 | // TellStepDuration return duration from last step. 140 | func (w *StopWatch) TellStepDuration() Duration { 141 | dur := w.duration(false) 142 | stepDur := dur - w.lastDur 143 | return stepDur 144 | } 145 | 146 | // GetWatch return step of of given index. 147 | func (w *StopWatch) GetWatch(index int) (d WatchDuration, ok bool) { 148 | if index >= 0 && index < len(w.durList) { 149 | return w.durList[index], true 150 | } 151 | return 152 | } 153 | 154 | // TellAllWatch return the list of step watch. 155 | func (w *StopWatch) TellAllWatch() []WatchDuration { 156 | return w.durList 157 | } 158 | -------------------------------------------------------------------------------- /time/stopwatch/stopwatch_test.go: -------------------------------------------------------------------------------- 1 | package stopwatch 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestStopwatch(t *testing.T) { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /time/stopwatch/watch_duration.go: -------------------------------------------------------------------------------- 1 | package stopwatch 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | // NewWatchDuration create a WatchDuration 9 | func NewWatchDuration(name string, dur Duration, batchNum int) *WatchDuration { 10 | d := &WatchDuration{} 11 | d.Init(name, dur, batchNum) 12 | return d 13 | } 14 | 15 | // WatchDuration represents duration of step watch. 16 | type WatchDuration struct { 17 | name string 18 | dur Duration 19 | batchNum int 20 | } 21 | 22 | // Init init the watch duration 23 | func (d *WatchDuration) Init(name string, dur Duration, batchNum int) { 24 | d.name = name 25 | d.dur = dur 26 | d.batchNum = batchNum 27 | } 28 | 29 | // String show the watch duration as string. 30 | func (d *WatchDuration) String() string { 31 | return fmt.Sprintf("%s\t%s", 32 | d.name, d.dur) 33 | } 34 | 35 | // Report show that watch string as string. 36 | func (d *WatchDuration) Report(idx int, lastDur Duration) string { 37 | var b strings.Builder 38 | 39 | if idx > 0 { 40 | b.WriteString(fmt.Sprintf("i=%d\t", idx)) 41 | } 42 | stepDur := d.dur - lastDur 43 | b.WriteString(fmt.Sprintf("n=%s\tt=%s\ts=%s", d.name, d.dur, stepDur)) 44 | if d.batchNum > 0 { 45 | atomicDur := stepDur / Duration(d.batchNum) 46 | b.WriteString(fmt.Sprintf("\tu(%d)=%s", d.batchNum, atomicDur)) 47 | } 48 | 49 | return b.String() 50 | } 51 | 52 | // Duration return duration of this step watch. 53 | func (d *WatchDuration) Duration() Duration { 54 | return d.dur 55 | } 56 | 57 | // Name return name of this step watch. 58 | func (d *WatchDuration) Name() string { 59 | return d.name 60 | } 61 | -------------------------------------------------------------------------------- /time/time_snapshot.go: -------------------------------------------------------------------------------- 1 | package time 2 | 3 | type Snapshot struct { 4 | } 5 | -------------------------------------------------------------------------------- /time/time_sys.go: -------------------------------------------------------------------------------- 1 | package time 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | //timing system 8 | var sys timeSys 9 | 10 | //time with adjust from network 11 | type Time struct { 12 | local time.Time //time from local runtime 13 | netAdjust time.Duration //adjust Duration from network 14 | } 15 | 16 | func (this *Time) Local() time.Time { 17 | return this.local 18 | } 19 | 20 | func (this *Time) NetAdjust() time.Duration { 21 | return this.netAdjust 22 | } 23 | 24 | //time system 25 | type timeSys struct { 26 | now Time 27 | frame uint64 28 | } 29 | 30 | func (this *timeSys) init() { 31 | 32 | } 33 | 34 | func (this *timeSys) autoUpdate() { 35 | 36 | } 37 | 38 | func (this *timeSys) Start() { 39 | 40 | } 41 | 42 | func (this *timeSys) Stop() { 43 | 44 | } 45 | 46 | func (this *timeSys) Frame() uint64 { 47 | return this.frame 48 | } 49 | 50 | func (this *timeSys) Update() { 51 | 52 | } 53 | 54 | func (this *timeSys) UpdateAdjust(_unix_time int64) error { 55 | return nil 56 | } 57 | 58 | //auto update local time 59 | func (this *timeSys) autoUpdate() { 60 | 61 | } 62 | 63 | //autoUpdate is autoUpdateTime duration 64 | func StartSys(autoUpdate Duration) { 65 | } 66 | 67 | func StopSys() {} 68 | 69 | func Frame() uint64 { 70 | return 0 71 | } 72 | 73 | func Update() (err error) { 74 | return nil 75 | } 76 | 77 | func UpdateAdjust(_unix_time int64) error { 78 | return nil 79 | } 80 | 81 | func RuntimeNow() time.Time { 82 | return time.Now() 83 | } 84 | -------------------------------------------------------------------------------- /unsafe/string.go: -------------------------------------------------------------------------------- 1 | package unsafe 2 | 3 | import ( 4 | "reflect" 5 | "unsafe" 6 | ) 7 | 8 | var ( 9 | //dynamic data address 10 | firstPointer = uintptr(unsafe.Pointer(new(int))) 11 | ) 12 | 13 | type Pointer unsafe.Pointer 14 | type Bytes []byte 15 | type String string 16 | 17 | //invalid receiver type Pointer 18 | //func (me Pointer) Writeable() bool { 19 | // addr := uintptr(me) 20 | // return addr >= firstPointer 21 | //} 22 | 23 | func Writeable(ptr Pointer) bool { 24 | addr := uintptr(ptr) 25 | return addr >= firstPointer 26 | } 27 | 28 | //how to do this? 29 | func (me Bytes) Writeable() bool { 30 | addr := uintptr(BytesPointer(me)) 31 | return addr >= firstPointer 32 | } 33 | 34 | func (me Bytes) Pointer() Pointer { 35 | return BytesPointer(me) 36 | } 37 | 38 | //check if a string's buffer is writeable 39 | func (me String) Writeable() bool { 40 | p := uintptr(StringPointer(string(me))) 41 | return p >= firstPointer 42 | } 43 | 44 | func (me String) Pointer() Pointer { 45 | return StringPointer(string(me)) 46 | } 47 | 48 | //return GoString's buffer slice(enable modify string) 49 | func StringBytes(s string) Bytes { 50 | var bh reflect.SliceHeader 51 | sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) 52 | bh.Data, bh.Len, bh.Cap = sh.Data, sh.Len, sh.Len 53 | return *(*Bytes)(unsafe.Pointer(&bh)) 54 | } 55 | 56 | // convert b to string without copy 57 | func BytesString(b []byte) String { 58 | return *(*String)(unsafe.Pointer(&b)) 59 | } 60 | 61 | // returns &s[0], which is not allowed in go 62 | func StringPointer(s string) Pointer { 63 | p := (*reflect.StringHeader)(unsafe.Pointer(&s)) 64 | return Pointer(p.Data) 65 | } 66 | 67 | // returns &b[0], which is not allowed in go 68 | func BytesPointer(b []byte) Pointer { 69 | p := (*reflect.SliceHeader)(unsafe.Pointer(&b)) 70 | return Pointer(p.Data) 71 | } 72 | -------------------------------------------------------------------------------- /unsafe/string_test.go: -------------------------------------------------------------------------------- 1 | package unsafe_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/vipally/gx/unsafe" 8 | ) 9 | 10 | //test result 11 | //String to bytes: 12 | //0 s= ptr(v)=0x51bd70 ptr(StringBytes(v)=0x51bd70 ptr([]byte(v)=0xc042021c58 13 | //1 s= ptr(v)=0x51bd70 ptr(StringBytes(v)=0x51bd70 ptr([]byte(v)=0xc042021c58 14 | //2 s=hello ptr(v)=0x51c2fa ptr(StringBytes(v)=0x51c2fa ptr([]byte(v)=0xc042021c58 15 | //3 s=hello ptr(v)=0x51c2fa ptr(StringBytes(v)=0x51c2fa ptr([]byte(v)=0xc042021c58 16 | //4 s= ptr(v)= ptr(StringBytes(v)= ptr([]byte(v)=0xc042021c58 17 | //5 s= ptr(v)= ptr(StringBytes(v)= ptr([]byte(v)=0xc042021c58 18 | //6 s=xello ptr(v)=0xc0420444b5 ptr(StringBytes(v)=0xc0420444b5 ptr([]byte(v)=0xc042021c58 19 | //7 s=xello ptr(v)=0xc0420444ba ptr(StringBytes(v)=0xc0420444ba ptr([]byte(v)=0xc042021c58 20 | //Bytes to string: 21 | //0 s= ptr(v)=0x5c38b8 ptr(StringBytes(v)=0x5c38b8 ptr(string(v)= 22 | //1 s=hello ptr(v)=0xc0420445e0 ptr(StringBytes(v)=0xc0420445e0 ptr(string(v)=0xc042021c38 23 | //Benchmark_Normal-4 1000000000 0.87 ns/op 24 | //Benchmark_Direct-4 2000000000 0.24 ns/op 25 | 26 | func TestPointer(t *testing.T) { 27 | s := []string{ 28 | "", 29 | "", 30 | "hello", 31 | "hello", 32 | fmt.Sprintf(""), 33 | fmt.Sprintf(""), 34 | fmt.Sprintf("hello"), 35 | fmt.Sprintf("hello"), 36 | } 37 | fmt.Println("String to bytes:") 38 | for i, v := range s { 39 | b := unsafe.StringBytes(v) 40 | b2 := []byte(v) 41 | if b.Writeable() { 42 | b[0] = 'x' 43 | } 44 | fmt.Printf("%d\ts=%5s\tptr(v)=%-12v\tptr(StringBytes(v)=%-12v\tptr([]byte(v)=%-12v\n", 45 | i, v, unsafe.StringPointer(v), b.Pointer(), unsafe.BytesPointer(b2)) 46 | } 47 | 48 | b := [][]byte{ 49 | []byte{}, 50 | []byte{'h', 'e', 'l', 'l', 'o'}, 51 | } 52 | fmt.Println("Bytes to string:") 53 | for i, v := range b { 54 | s1 := unsafe.BytesString(v) 55 | s2 := string(v) 56 | fmt.Printf("%d\ts=%5s\tptr(v)=%-12v\tptr(StringBytes(v)=%-12v\tptr(string(v)=%-12v\n", 57 | i, s1, unsafe.BytesPointer(v), s1.Pointer(), unsafe.StringPointer(s2)) 58 | } 59 | 60 | } 61 | 62 | const N = 3000000 63 | 64 | func Benchmark_Normal(b *testing.B) { 65 | for i := 1; i < N; i++ { 66 | s := fmt.Sprintf("12345678901234567890123456789012345678901234567890") 67 | bb := []byte(s) 68 | bb[0] = 'x' 69 | s = string(bb) 70 | s = s 71 | } 72 | } 73 | func Benchmark_Direct(b *testing.B) { 74 | for i := 1; i < N; i++ { 75 | s := fmt.Sprintf("12345678901234567890123456789012345678901234567890") 76 | bb := unsafe.StringBytes(s) 77 | bb[0] = 'x' 78 | s = s 79 | } 80 | } 81 | --------------------------------------------------------------------------------