From 2d49e12bd013529560081371679695fd83998a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=91=E5=A4=9C=E8=B7=AF=E4=BA=BA?= Date: Thu, 17 Feb 2022 12:18:17 +0800 Subject: [PATCH] change XMM test code --- example/xmm-test00.go | 15 ++++++- example/xmm-test01.go | 23 +++++++++- example/xmm-test02.go | 26 ++++++++++-- example/xmm-test03.go | 99 ++++++++++++++++++++++++++++++++++--------- 4 files changed, 138 insertions(+), 25 deletions(-) diff --git a/example/xmm-test00.go b/example/xmm-test00.go index 96f9a46..11ec646 100644 --- a/example/xmm-test00.go +++ b/example/xmm-test00.go @@ -1,4 +1,9 @@ /* + XMM Example 00 + + Goal: How to use XMM quickly and easily + Description: An example of how to use the XMM memory library quickly and easily. + XMM 示例00 目标:如何简单快速使用XMM @@ -9,16 +14,19 @@ package main import ( //xmm "xmm/src" - xmm "github.com/heiyeluren/xmm/src" + xmm "github.com/heiyeluren/xmm" "fmt" "unsafe" ) func main() { + //Initialising XMM objects //初始化XMM对象 f := &xmm.Factory{} + // Request a memory block from the operating system + //If memory usage reaches 60%, asynchronous automatic expansion is performed, each time 256MB of memory is expanded asynchronously (fixed value), the value of 0.6 can be configured independently //从操作系统申请一个内存块 //如果内存使用达到60%,就进行异步自动扩容,每次异步扩容256MB内存(固定值),0.6这个数值可以自主配置 mm, err := f.CreateMemory(0.6) @@ -26,6 +34,7 @@ func main() { panic("CreateMemory fail ") } + // manipulate int types, request memory and assign a value //操作int类型,申请内存后赋值 var tmpNum int = 9527 p, err := mm.Alloc(unsafe.Sizeof(tmpNum)) @@ -33,15 +42,18 @@ func main() { panic("Alloc fail ") } Id := (*int)(p) + // Write the set number assignment to the XMM memory //把设定好的数字赋值写入到XMM内存中 *Id = tmpNum + // To manipulate string types, XMM provides the From() interface to get a pointer directly and the string will be stored in XMM //操作字符串类型,XMM提供了From()接口,可以直接获得一个指针,字符串会存储在XMM中 Name, err := mm.From("heiyeluren") if err != nil { panic("Alloc fail ") } + // Output variables and memory addresses from XMM memory //从XMM内存中输出变量和内存地址 fmt.Println("\n===== XMM X(eXtensible) Memory Manager example 00 ======\n") fmt.Println("\n-- Memory data status --\n") @@ -50,6 +62,7 @@ func main() { fmt.Println("\n===== Example test success ======\n") + //Free the Id,Name memory block //释放Id,Name内存块 mm.Free(uintptr(p)) mm.FreeString(Name) diff --git a/example/xmm-test01.go b/example/xmm-test01.go index 84eb265..a4f3a4f 100644 --- a/example/xmm-test01.go +++ b/example/xmm-test01.go @@ -1,14 +1,18 @@ /* XMM 简单示例 - 01 + XMM Simple Example - 01 目标:如何在结构体中使用XMM - 说明:示例如何结构体类场景如何使用XMM内存库 + Objective: How to use XMM in structures + + 说明:示例如何结构体类场景如何使用XMM内存库 + Description: Example of how to use the XMM memory library in a structure class scenario */ package main import ( //xmm "xmm/src" - xmm "github.com/heiyeluren/xmm/src" + xmm "github.com/heiyeluren/xmm" "fmt" "unsafe" ) @@ -16,6 +20,7 @@ import ( func main() { //定义一个类型(结构体) + // Define a type (structure) type User struct { Id uint Name string @@ -25,15 +30,21 @@ func main() { } //初始化XMM对象 + // Initialise the XMM object f := &xmm.Factory{} + //从操作系统申请一个内存块 //如果内存使用达到60%,就进行异步自动扩容,每次异步扩容256MB内存(固定值),0.6这个数值可以自主配置 + // Request a memory block from the operating system + //If memory usage reaches 60%, asynchronous automatic expansion is performed, each time 256MB of memory is expanded asynchronously (fixed value), the value of 0.6 can be configured independently + mm, err := f.CreateMemory(0.6) if err != nil { panic("CreateMemory fail ") } //自己从内存块中申请一小段自己想用的内存 + // Request a small section of memory from the memory block yourself that you want to use size := unsafe.Sizeof(User{}) p, err := mm.Alloc(size) if err != nil { @@ -41,6 +52,7 @@ func main() { } //使用该内存块,进行结构体元素赋值 + // Use this memory block for structure element assignment user := (*User)(p) user.Id = 1 user.Age = 18 @@ -48,6 +60,7 @@ func main() { user.Email = "heiyeluren@example.com" //输出变量,打印整个结构体等 + // Output variables, print entire structures, etc. fmt.Println("\n===== XMM X(eXtensible) Memory Manager example 01 ======\n") fmt.Println("\n-- Memory data status --\n") @@ -55,16 +68,22 @@ func main() { fmt.Println("User data: \t", user) //释放内存块(实际是做mark标记操作) + //Free memory blocks (actually doing a mark mark operation) mm.Free(uintptr(p)) //Free()后再看看变量值,只是针对这个内存块进行mark标记动作,并未彻底从内存中释放(XMM设计机制,降低实际gc回收空闲时间) //XMM内部会有触发gc的机制,主要是内存容量,参数TotalGCFactor=0.0004,目前如果要配置,需要自己修改这个常量,一般不用管它,Free()操作中有万分之4的概率会命中触发gc~ //GC触发策略:待释放内存 > 总内存 * 万分之4 会触发gc动作 + //After Free() and then look at the variable value, only for this memory block to mark mark action, not completely released from memory (XMM design mechanism to reduce the actual gc recovery idle time) + //XMM will have an internal mechanism to trigger gc, mainly memory capacity, parameter TotalGCFactor=0.0004, currently if you want to configure, you need to modify this constant yourself, generally do not bother with it, Free() operation has a 4 in 10,000 probability of hitting the trigger gc ~ + //GC trigger policy: memory to be freed > total memory * 4 in 10,000 will trigger gc action + fmt.Println("\n-- Memory data status after XMM.Free() --\n") fmt.Println("memory ptr addr:\t", p) fmt.Println("User data:\t\t", user) //结束 + // End fmt.Println("\n===== Example test success ======\n") } diff --git a/example/xmm-test02.go b/example/xmm-test02.go index 7ac2d02..a964e8f 100644 --- a/example/xmm-test02.go +++ b/example/xmm-test02.go @@ -1,25 +1,31 @@ /* XMM 简单示例 - 02 + XMM Simple Example - 02 目标:使用XMM构建一个单链表程序 + Objective: To build a single linked table program using XMM + 说明:示例复杂场景中使用XMM内存库 + Description: Example complex scenario using the XMM memory library */ package main import ( //xmm "xmm/src" - xmm "github.com/heiyeluren/xmm/src" + xmm "github.com/heiyeluren/xmm" "fmt" "unsafe" ) //定义一个链表的节点结构 +// Define the node structure of a chain table type XListNode struct { Val int Next *XListNode } //单链表主结构 +/ Single linked table main structure type XList struct { Head *XListNode //Tail *XListNode @@ -27,6 +33,7 @@ type XList struct { //初始化链表 +//Initialize the chain table func (l *XList) Init( mm xmm.XMemory ) { Node,err := mm.Alloc(unsafe.Sizeof(XListNode{})) if err != nil { @@ -39,6 +46,7 @@ func (l *XList) Init( mm xmm.XMemory ) { } //链表增加节点 +//Link table adds nodes func (l *XList) Append(i int, mm xmm.XMemory) { h := l.Head for h.Next != nil { @@ -57,6 +65,7 @@ func (l *XList) Append(i int, mm xmm.XMemory) { } //遍历所有链表节点并打印 +// iterate through all the chain table nodes and print func (l *XList) Show() { h := l.Head //fmt.Println(h.Val) @@ -67,12 +76,14 @@ func (l *XList) Show() { } //释放整个链表结构 +//Releasing the entire linked table structure func (l *XList) Destroy(mm xmm.XMemory) { cnt := 0 h := l.Head //fmt.Println(h.Val) //统计需要释放总数 + // Count the total number of releases required for h.Next != nil { h = h.Next cnt++ @@ -81,6 +92,7 @@ func (l *XList) Destroy(mm xmm.XMemory) { //fmt.Println("item count:", cnt) //循环释放所有内存 + // Loop to free all memory for i := 0; i <= cnt; i++ { h := l.Head pre := l.Head @@ -95,41 +107,49 @@ func (l *XList) Destroy(mm xmm.XMemory) { } //主函数 +// Main functions func main() { //初始化XMM对象 + // Initialise the XMM object f := &xmm.Factory{} + //从操作系统申请一个内存块,如果内存使用达到60%,就进行异步自动扩容,每次异步扩容256MB内存(固定值) + // Request a block of memory from the OS and perform asynchronous auto-expansion if memory usage reaches 60%, 256MB of memory per asynchronous expansion (fixed value) mm, err := f.CreateMemory(0.6) if err != nil { panic("CreateMemory fail ") } //要生成的数字列表 + // List of numbers to be generated list := []int{ 2, 4, 3} fmt.Println("\n===== XMM X(eXtensible) Memory Manager example 02 - LinkedList ======\n") //初始化链表 + //Initialize LinkedList l := &XList{} l.Init(mm) fmt.Println("") //把元素压入链表 + // Pressing elements into a LinkedList for i := 0; i < len(list); i++ { l.Append(list[i], mm) } fmt.Println("") - //遍历所有链表数据 + // Iterate through all the linked table data l.Show() fmt.Println("") - //释放所有链表内存 + //Free all LinkedList memory l.Destroy(mm) //结束 + //End fmt.Println("\n===== Example test success ======\n") } diff --git a/example/xmm-test03.go b/example/xmm-test03.go index 98832de..b607b56 100644 --- a/example/xmm-test03.go +++ b/example/xmm-test03.go @@ -4,12 +4,17 @@ 目标:使用XMM构建一个哈希表程序 说明:示例复杂场景中使用XMM内存库 + + XMM Simple Example - 03 + + Objective: To build a hash table program using XMM + Description: Example complex scenario using the XMM memory library */ package main import ( //xmm "xmm/src" - xmm "github.com/heiyeluren/xmm/src" + xmm "github.com/heiyeluren/xmm" "strconv" "strings" "fmt" @@ -18,39 +23,49 @@ import ( ) //定义哈希表桶数量 +// Define the number of hash table buckets const HashTableBucketMax = 1024 //定义哈希表存储实际KV节点存储数据 +// Define hash tables to store actual KV node storage data type XEntity struct { - Key string //Key,必须是字符串 - Value string //Value值,是字符串,把interface{}转json + Key string //Key必须是字符串 Key, must be a string + Value string //Value是字符串,从interface转成json格式 Value value, a string, convert interface{} to json } //定义哈希表中单个桶结构(开拉链法) +// Define a single bucket structure in a hash table (open zip method) type XBucket struct { - Data *XEntity //当前元素KV - Next *XBucket //如果冲突情况开拉链法下一个节点的Next指针 + Data *XEntity //当前元素KV Current element KV + Next *XBucket //如果冲突情况开拉链法下一个节点的Next指针 Next pointer to the next node of the open zip method if a conflict situation arises } //哈希表入口主结构HashTable +// HashTable entry main structure HashTable type XHashTable struct { - Table []*XBucket //哈希表所有桶存储池 - Size uint64 //哈希表已存总元素数量 - mm xmm.XMemory //XMM内存管理对象 + Table []*XBucket //哈希表所有桶存储池 Hash table all bucket storage pool + Size uint64 //哈希表已存总元素数量 Total number of elements stored in the hash table + mm xmm.XMemory //XMM内存管理对象 XMM Memory Management Objects } //初始化哈希表 +// Initialize the hash table func (h *XHashTable) Init( mm xmm.XMemory ) { //设置需要申请多大的连续数组内存空间,如果是动态扩容情况建议设置为16,目前是按照常量桶大小 + // Set how much contiguous array memory space to request, 16 is recommended for dynamic expansion cases, currently it is based on the constant bucket size cap := HashTableBucketMax initCap := uintptr(cap) + //申请按照设定总桶数量大小的内存块 + // Request a block of memory of the set total bucket size p, err := mm.AllocSlice(unsafe.Sizeof(&XBucket{}), initCap, initCap) if err != nil { panic("Alloc fail") } + //把申请的内存库给哈希表总存储池,初始化数量和XMM内存对象 + // give the requested memory bank to the total hash table storage pool, initialize the number and XMM memory objects h.Table = *(*[]*XBucket)(p) h.Size = 0 h.mm = mm @@ -59,17 +74,22 @@ func (h *XHashTable) Init( mm xmm.XMemory ) { } //释放整个哈希表 +//Free the entire hash table func (h *XHashTable) Destroy() (error) { return nil } //哈希表 Set数据 +///hash tables Set data func (h *XHashTable) Set(Key string, Value interface{}) (error) { //-------------- - // 构造Entity + // 构造Entity + // Constructing Entity //-------------- + //Value进行序列化 + //Value for serialisation jdata, err := json.Marshal(Value) if err != nil { fmt.Println("Set() op Value [", Value, "] json encode fail") @@ -78,6 +98,7 @@ func (h *XHashTable) Set(Key string, Value interface{}) (error) { sValue := string(jdata) //申请三个内存,操作字符串类型,XMM提供了From()接口,可以直接获得一个指针,字符串会存储在XMM中 + // request three memory, manipulate string types, XMM provides a From() interface to get a pointer directly, the string will be stored in XMM //size := unsafe.Sizeof(User{}) p, err := h.mm.Alloc(unsafe.Sizeof(XEntity{})) if err != nil { @@ -93,18 +114,21 @@ func (h *XHashTable) Set(Key string, Value interface{}) (error) { } //拼装Entity + // Assembling Entity pEntity := (*XEntity)(p) pEntity.Key = pKey pEntity.Value = pVal //--------------- // 挂接到Bucket + // Hook up to Bucket //--------------- bucketIdx := getBucketSlot(Key) //bucketSize := unsafe.Sizeof(&XBucket{}) bucket := h.Table[bucketIdx] //构造bucket + // Constructing a bucket pb, err := h.mm.Alloc(unsafe.Sizeof(XBucket{})) if err != nil { panic("Alloc fail ") @@ -114,6 +138,7 @@ func (h *XHashTable) Set(Key string, Value interface{}) (error) { pBucket.Next = nil //如果槽没有被占用则压入数据后结束 + // end after pressing in data if the slot is not occupied if bucket == nil { h.Table[bucketIdx] = pBucket h.Size = h.Size + 1 @@ -121,14 +146,15 @@ func (h *XHashTable) Set(Key string, Value interface{}) (error) { } //使用开拉链法把KV放入到冲突的槽中 + // Use the unzipping method to place the KV in the conflicting slot var k string for bucket != nil { k = bucket.Data.Key //如果发现有重名key,则直接替换Value + // If a duplicate key is found, the Value is replaced directly if strings.Compare(strings.ToLower(Key), strings.ToLower(k)) == 0 { - //释放原Value内存,挂接新Value - //pv := bucket.Data.Value - //mm.Free(pv) + //挂接新Value + // mount the new Value pValNew, err := h.mm.From(sValue) if err != nil { panic("Alloc fail ") @@ -137,18 +163,21 @@ func (h *XHashTable) Set(Key string, Value interface{}) (error) { return nil } //如果是最后一个拉链的节点,则把当前KV挂上去 + // If it is the last node to zip, hook up the current KV if bucket.Next == nil { bucket.Next = pBucket h.Size = h.Size + 1 return nil } //没找到则继续循环 + // continue the cycle if not found bucket = bucket.Next } return nil } //哈希表 Get数据 +// Hash Table Get Data func (h *XHashTable) Get(Key string) (interface{}, error) { var k string var val interface{} @@ -158,6 +187,7 @@ func (h *XHashTable) Get(Key string) (interface{}, error) { for bucket != nil { k = bucket.Data.Key //如果查找到相同Key开始返回数据 + // If the same Key is found start returning data if strings.Compare(strings.ToLower(Key), strings.ToLower(k)) == 0 { //bTmp := []byte(k) err := json.Unmarshal([]byte(bucket.Data.Value), &val) @@ -168,6 +198,7 @@ func (h *XHashTable) Get(Key string) (interface{}, error) { return val, nil } //没找到则继续向后查找 + // continue to search backwards if not found if bucket.Next != nil { bucket = bucket.Next continue @@ -176,38 +207,47 @@ func (h *XHashTable) Get(Key string) (interface{}, error) { return nil, nil } -//Delete数据 +//哈希表 Delete数据 +// Hash Table Delete Data func (h *XHashTable) Remove(Key string)(error) { var k string bucketIdx := getBucketSlot(Key) bucket := h.Table[bucketIdx] //如果节点不存在直接返回 + // return directly if node does not exist if bucket == nil { return nil } //进行节点判断处理 + // Perform node judgement processing tmpBucketPre := bucket - linkDepthSize := 0 //存储当前开拉链第几层 + linkDepthSize := 0 //存储当前开拉链第几层 Store the current layer of open zips for bucket != nil { linkDepthSize = linkDepthSize + 1 - tmpBucketPre = bucket //把当前节点保存下来 + tmpBucketPre = bucket //把当前节点保存下来 Save the current node k = bucket.Data.Key + //如果查找了相同的Key进行删除操作 + // If the same Key is found for the delete operation if strings.Compare(strings.ToLower(Key), strings.ToLower(k)) == 0 { + //如果是深度第一层的拉链,把下一层拉链替换顶层拉链后返回 + // In the case of a deep first layer of zips, replace the next layer of zips with the top layer and return if linkDepthSize == 1 { //如果是终点了直接当前桶置为nil + //If it's the end of the line set the current bucket to nil if bucket.Next == nil { h.Table[bucketIdx] = nil - } else { //如果还有其他下一级开拉链元素则替代本级元素 + } else { //如果还有其他下一级开拉链元素则替代本级元素 If there are other open zip elements at the next level, they replace the element at this level h.Table[bucketIdx] = bucket.Next } - } else { //如果查到的可以不是第一级元素,则进行前后替换 + } else { //如果查到的可以不是第一级元素,则进行前后替换 If the element found can be other than the first level, then a back and forth substitution is made tmpBucketPre.Next = bucket.Next } //释放内存 + //Free memory //p := bucket.Data.Key //h.mm.Free(p) h.mm.FreeString(bucket.Data.Key) @@ -218,6 +258,7 @@ func (h *XHashTable) Remove(Key string)(error) { return nil } //如果还没找到,继续遍历把下一节点升级为当前节点 + // If not found, continue traversing to upgrade the next node to the current one if bucket.Next != nil { bucket = bucket.Next continue @@ -226,18 +267,21 @@ func (h *XHashTable) Remove(Key string)(error) { return nil } -//获取目前总元素数量 +//获取哈希表元素总数量 +// Get the total number of hash table elements func (h *XHashTable) getSize() (uint64) { return h.Size } -//获取槽的计算位置 +//获取指定Key在哈希表中槽的位置 +// Get the position of the specified Key in the hash table slot func getBucketSlot(key string) uint64 { hash := BKDRHash(key) return hash % HashTableBucketMax } //哈希函数(采用冲突率低性能高的 BKDR Hash算法,也可采用 MurmurHash) +// Hash function (using BKDR Hash algorithm with low conflict rate and high performance, MurmurHash can also be used) func BKDRHash(key string) uint64 { var str []byte = []byte(key) // string transfer format to []byte seed := uint64(131) // 31 131 1313 13131 131313 etc.. @@ -251,11 +295,15 @@ func BKDRHash(key string) uint64 { //主函数 +// Main functions func main() { //初始化XMM对象 + // Initialise the XMM object f := &xmm.Factory{} + //从操作系统申请一个内存块,如果内存使用达到60%,就进行异步自动扩容,每次异步扩容256MB内存(固定值) + // Request a block of memory from the OS and perform asynchronous auto-expansion if memory usage reaches 60%, 256MB of memory per asynchronous expansion (fixed value) mm, err := f.CreateMemory(0.6) if err != nil { panic("CreateMemory fail ") @@ -265,18 +313,22 @@ func main() { //初始化哈希表 + // Initialize the hash table h := &XHashTable{} h.Init(mm) //简单数据类型压入哈希表 + // Simple data types pressed into a hash table fmt.Println("\n---- Simple data type hash Set/Get -----") //压入一批数据 + // Press in a batch of data for i := 0; i < 5; i++ { fmt.Println("Hash Set: ", strconv.Itoa(i), strconv.Itoa(i*10)) h.Set(strconv.Itoa(i), strconv.Itoa(i*10)) } //读取数据 + // Read data for i := 0; i < 5; i++ { fmt.Print("Hash Get: ", i, " ") fmt.Println(h.Get(strconv.Itoa(i))) @@ -286,9 +338,11 @@ func main() { //存取复合型数据结构到哈希表 + // Accessing compound data structures to hash tables fmt.Println("\n---- Mixed data type hash Set/Get -----") //构造测试数据 + // Constructing test data testKV := make(map[string]interface{}) testKV["map01"] = map[string]string{"name":"heiyeluren", "email":"heiyeluren@example.com"} testKV["array01"] = [...]uint{9527, 2022, 8} @@ -296,11 +350,13 @@ func main() { //fmt.Println(testKV) //压入数据到哈希表 + // Pressing data into a hash table for k, v := range testKV { fmt.Print("Hash Set: ", k, " \n") h.Set(k, v) } //读取哈希表 + // Read the hash table for k, _ := range testKV { fmt.Print("Hash Get: ", k, " ") fmt.Println(h.Get(k)) @@ -308,6 +364,7 @@ func main() { fmt.Println("Hash Table Size: ", h.getSize()) //覆盖同样Key数据 + // Overwrite the same Key data fmt.Println("\n---- Overwrite data hash Set/Get -----") for k, _ := range testKV { fmt.Print("Cover Hash Set: ", k, " \n") @@ -320,6 +377,7 @@ func main() { fmt.Println("Hash Table Size: ", h.getSize()) //删除Key + // Delete Key fmt.Println("\n---- Delete data Remove op -----") k1 := "test01" @@ -336,6 +394,7 @@ func main() { fmt.Println(h.Get(k1)) //读取老的key看看有没有受影响 + // Read the old key to see if it is affected for k, _ := range testKV { fmt.Print("Hash Get: ", k, " ") fmt.Println(h.Get(k)) @@ -344,9 +403,11 @@ func main() { //释放所有哈希表 + // Free all hash tables h.Destroy() //结束 + //End fmt.Println("\n===== Example test success ======\n") }