From e3107bcc684d88647156569dcbd336b6fa5b9edb Mon Sep 17 00:00:00 2001 From: John Date: Mon, 16 Apr 2018 17:59:23 +0800 Subject: [PATCH] =?UTF-8?q?garray=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/garray/garray_sorted_int.go | 105 -------------- g/container/garray/garray_sorted_interface.go | 132 ++++++++++++++++++ geg/container/garray.go | 28 ++++ 3 files changed, 160 insertions(+), 105 deletions(-) delete mode 100644 g/container/garray/garray_sorted_int.go create mode 100644 g/container/garray/garray_sorted_interface.go create mode 100644 geg/container/garray.go diff --git a/g/container/garray/garray_sorted_int.go b/g/container/garray/garray_sorted_int.go deleted file mode 100644 index 8e13c109b..000000000 --- a/g/container/garray/garray_sorted_int.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://gitee.com/johng/gf. - -package garray - -import ( - "sync" - "sort" - "gitee.com/johng/gf/g/encoding/gbinary" - "bytes" -) - -type SortedIntArray struct { - mu sync.RWMutex // 互斥锁 - array []int // 底层数组 - compareFunc func(v1, v2 int) int // 比较函数,返回值 -1: v1 < v2;0: v1==v2;1: v1 > v2 -} - -func NewSortedIntArray(size int, cap ... int) *SortedIntArray { - a := &SortedIntArray{} - if len(cap) > 0 { - a.array = make([]int, size, cap[0]) - } else { - a.array = make([]int, size) - } - a.compareFunc = func(v1, v2 int) int { - if v1 < v2 { - return -1 - } - if v1 > v2 { - return 0 - } - return 0 - } - return a -} - -// 添加加数据项 -func (a *SortedIntArray) Add(value int) { - a.mu.Lock() - a.array = append(a.array, value) - a.mu.Unlock() -} - -// 获取指定索引的数据项, 调用方注意判断数组边界 -func (a *SortedIntArray) Get(index int) int { - a.mu.RLock() - value := a.array[index] - a.mu.RUnlock() - return value -} - -// 删除指定索引的数据项, 调用方注意判断数组边界 -func (a *SortedIntArray) Remove(index int) { - a.mu.Lock() - a.array = append(a.array[ : index], a.array[index + 1 : ]...) - a.mu.RUnlock() -} - -// 数组长度 -func (a *SortedIntArray) Len() int { - a.mu.RLock() - length := len(a.array) - a.mu.RUnlock() - return length -} - -// 返回原始数据数组 -func (a *SortedIntArray) Slice() []int { - a.mu.RLock() - array := a.array - a.mu.RUnlock() - return array -} - -// 查找指定数值的索引位置,返回索引位置(具体匹配位置或者最后对比位置)及查找结果 -func (a *SortedIntArray) Search(value int) (int, int) { - a.mu.RLock() - min := 0 - max := len(a.array) - 1 - mid := 0 - cmp := -2 - for { - if cmp == 0 || min > max { - break - } - for { - mid = int((min + max) / 2) - cmp = a.compareFunc(a.array[mid], value) - switch cmp { - case -1 : max = mid - 1 - case 0 : - case 1 : min = mid + 1 - } - if cmp == 0 || min > max { - break - } - } - } - a.mu.RUnlock() - return mid, cmp -} \ No newline at end of file diff --git a/g/container/garray/garray_sorted_interface.go b/g/container/garray/garray_sorted_interface.go new file mode 100644 index 000000000..7207bab68 --- /dev/null +++ b/g/container/garray/garray_sorted_interface.go @@ -0,0 +1,132 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package garray + +import ( + "sync" + "gitee.com/johng/gf/g/container/gtype" +) + +// 默认按照从低到高进行排序 +type SortedArray struct { + mu sync.RWMutex // 互斥锁 + array []interface{} // 底层数组 + unique *gtype.Bool // 是否要求不能重复 + compareFunc func(v1, v2 interface{}) int // 比较函数,返回值 -1: v1 < v2;0: v1 == v2;1: v1 > v2 +} + +func NewSortedArray(size int, cap int, compareFunc func(v1, v2 interface{}) int) *SortedArray { + return &SortedArray{ + unique : gtype.NewBool(), + array : make([]interface{}, size, cap), + compareFunc : compareFunc, + } +} + +// 添加加数据项 +func (a *SortedArray) Add(value interface{}) { + index, cmp := a.Search(value) + if a.unique.Val() && cmp == 0 { + return + } + if index < 0 { + a.mu.Lock() + a.array = append(a.array, value) + a.mu.Unlock() + return + } + // 加到指定索引后面 + if cmp > 0 { + index++ + } + a.mu.Lock() + rear := append([]interface{}{}, a.array[index : ]...) + a.array = append(a.array[0 : index], value) + a.array = append(a.array, rear...) + a.mu.Unlock() +} + +// 获取指定索引的数据项, 调用方注意判断数组边界 +func (a *SortedArray) Get(index int) interface{} { + a.mu.RLock() + value := a.array[index] + a.mu.RUnlock() + return value +} + +// 删除指定索引的数据项, 调用方注意判断数组边界 +func (a *SortedArray) Remove(index int) { + a.mu.Lock() + a.array = append(a.array[ : index], a.array[index + 1 : ]...) + a.mu.RUnlock() +} + +// 数组长度 +func (a *SortedArray) Len() int { + a.mu.RLock() + length := len(a.array) + a.mu.RUnlock() + return length +} + +// 返回原始数据数组 +func (a *SortedArray) Slice() []interface{} { + a.mu.RLock() + array := a.array + a.mu.RUnlock() + return array +} + +// 查找指定数值的索引位置,返回索引位置(具体匹配位置或者最后对比位置)及查找结果 +func (a *SortedArray) Search(value interface{}) (int, int) { + if len(a.array) == 0 { + return -1, -2 + } + a.mu.RLock() + min := 0 + max := len(a.array) - 1 + mid := 0 + cmp := -2 + for { + if cmp == 0 || min > max { + break + } + for { + mid = int((min + max) / 2) + cmp = a.compareFunc(value, a.array[mid]) + switch cmp { + case -1 : max = mid - 1 + case 0 : + case 1 : min = mid + 1 + } + if cmp == 0 || min > max { + break + } + } + } + a.mu.RUnlock() + return mid, cmp +} + +// 清理数组中重复的元素项 +func (a *SortedArray) DoUnique() { + a.mu.Lock() + for i := 0; ; i ++ { + if i == len(a.array) - 1 { + break + } + for { + if a.compareFunc(a.array[i], a.array[i + 1]) == 0 { + a.array = append(a.array[ : i + 1], a.array[i + 1 + 1 : ]...) + } else { + break + } + } + + } + a.mu.Unlock() +} \ No newline at end of file diff --git a/geg/container/garray.go b/geg/container/garray.go new file mode 100644 index 000000000..c58029eb9 --- /dev/null +++ b/geg/container/garray.go @@ -0,0 +1,28 @@ +package main + +import ( + "fmt" + "gitee.com/johng/gf/g/container/garray" +) + + +func main () { + a := garray.NewSortedArray(0, 0, func(v1, v2 interface{}) int { + if v1.(int) < v2.(int) { + return -1 + } + if v1.(int) > v2.(int) { + return 1 + } + return 0 + }) + a.Add(10) + a.Add(20) + a.Add(30) + a.Add(1) + a.Add(1) + a.Add(1) + a.Add(1) + a.DoUnique() + fmt.Println(a.Slice()) +}