mirror of
https://github.com/pyihe/go-pkg.git
synced 2025-10-16 04:50:44 +08:00
403 lines
8.2 KiB
Go
403 lines
8.2 KiB
Go
package listpkg
|
||
|
||
import (
|
||
"container/list"
|
||
"reflect"
|
||
"sync"
|
||
)
|
||
|
||
type HashList struct {
|
||
mu *sync.RWMutex
|
||
data map[interface{}]*list.List
|
||
}
|
||
|
||
func NewHList() *HashList {
|
||
return &HashList{
|
||
mu: &sync.RWMutex{},
|
||
data: make(map[interface{}]*list.List),
|
||
}
|
||
}
|
||
|
||
// LPush 向队首添加数据
|
||
func (hl *HashList) LPush(key interface{}, data ...interface{}) (n int) {
|
||
hl.mu.Lock()
|
||
n = hl.push(true, key, data...)
|
||
hl.mu.Unlock()
|
||
|
||
return
|
||
}
|
||
|
||
// LPop 从队首取出数据
|
||
func (hl *HashList) LPop(key interface{}) (data interface{}) {
|
||
hl.mu.Lock()
|
||
data = hl.pop(true, key)
|
||
hl.mu.Unlock()
|
||
return
|
||
}
|
||
|
||
// RPush 向队尾添加数据
|
||
func (hl *HashList) RPush(key interface{}, data ...interface{}) (n int) {
|
||
hl.mu.Lock()
|
||
n = hl.push(false, key, data...)
|
||
hl.mu.Unlock()
|
||
return
|
||
}
|
||
|
||
// RPop 从队尾取数据
|
||
func (hl *HashList) RPop(key interface{}) (data interface{}) {
|
||
hl.mu.Lock()
|
||
data = hl.pop(false, key)
|
||
hl.mu.Unlock()
|
||
return
|
||
}
|
||
|
||
// Index 根据索引查找数据
|
||
func (hl *HashList) Index(key interface{}, idx int) (data interface{}) {
|
||
hl.mu.RLock()
|
||
defer hl.mu.RUnlock()
|
||
|
||
record := hl.data[key]
|
||
ok, newIndex := validIndex(record, idx)
|
||
if !ok {
|
||
return
|
||
}
|
||
|
||
if element := index(record, newIndex); element != nil {
|
||
data = element.Value
|
||
}
|
||
return
|
||
}
|
||
|
||
// Remove 删除数据
|
||
// count为删除个数
|
||
// count == 0 从队首开始删除所有的data
|
||
// count > 0 从队首开始删除count个data
|
||
// count < 0 从队尾开始删除count个data
|
||
func (hl *HashList) Remove(key interface{}, data interface{}, count int) (rmCount int) {
|
||
hl.mu.Lock()
|
||
defer hl.mu.Unlock()
|
||
|
||
record := hl.data[key]
|
||
if record == nil || record.Len() == 0 {
|
||
return
|
||
}
|
||
var es []*list.Element
|
||
switch {
|
||
case count > 0:
|
||
for e := record.Front(); e != nil && len(es) < count; e = e.Next() {
|
||
if reflect.DeepEqual(e.Value, data) {
|
||
es = append(es, e)
|
||
}
|
||
}
|
||
case count < 0:
|
||
for e := record.Back(); e != nil && len(es) < count; e = e.Prev() {
|
||
if reflect.DeepEqual(e.Value, data) {
|
||
es = append(es, e)
|
||
}
|
||
}
|
||
default:
|
||
for e := record.Front(); e != nil; e = e.Next() {
|
||
if reflect.DeepEqual(e.Value, data) {
|
||
es = append(es, e)
|
||
}
|
||
}
|
||
}
|
||
for _, e := range es {
|
||
record.Remove(e)
|
||
}
|
||
rmCount = len(es)
|
||
return
|
||
}
|
||
|
||
func (hl *HashList) UnsafeLInsert(key interface{}, pivot, val interface{}) int {
|
||
record := hl.data[key]
|
||
pEle := find(record, pivot)
|
||
if pEle == nil {
|
||
return -1
|
||
}
|
||
record.InsertBefore(val, pEle)
|
||
return record.Len()
|
||
}
|
||
|
||
// LInsert 在指定位置前面插入数据
|
||
// 插入失败返回-1
|
||
// 插入成功返回队列长度
|
||
func (hl *HashList) LInsert(key interface{}, mark, val interface{}) int {
|
||
hl.mu.Lock()
|
||
defer hl.mu.Unlock()
|
||
|
||
record := hl.data[key]
|
||
pElement := find(record, mark)
|
||
if pElement == nil {
|
||
return -1
|
||
}
|
||
record.InsertBefore(val, pElement)
|
||
return record.Len()
|
||
}
|
||
|
||
// RInsert 在指定位置后面插入数据
|
||
// 插入失败返回-1
|
||
// 插入成功返回队列长度
|
||
func (hl *HashList) RInsert(key interface{}, mark, val interface{}) int {
|
||
hl.mu.Lock()
|
||
defer hl.mu.Unlock()
|
||
|
||
record := hl.data[key]
|
||
pElement := find(record, mark)
|
||
if pElement == nil {
|
||
return -1
|
||
}
|
||
record.InsertAfter(val, pElement)
|
||
|
||
return record.Len()
|
||
}
|
||
|
||
// Set 将索引处的数据设置为val
|
||
func (hl *HashList) Set(key interface{}, idx int, val interface{}) (ok bool) {
|
||
hl.mu.Lock()
|
||
defer hl.mu.Unlock()
|
||
|
||
record := hl.data[key]
|
||
data := index(record, idx)
|
||
if data != nil {
|
||
data.Value = val
|
||
ok = true
|
||
}
|
||
return
|
||
}
|
||
|
||
func (hl *HashList) UnsafeRange(key interface{}, start, end int) (result []interface{}) {
|
||
record := hl.data[key]
|
||
if record == nil || record.Len() == 0 {
|
||
return nil
|
||
}
|
||
length := record.Len()
|
||
start, end = handleIndex(length, start, end)
|
||
if start > end || start >= length {
|
||
return nil
|
||
}
|
||
|
||
mid := length >> 1
|
||
if end <= mid || end-mid < mid-start {
|
||
flag := 0
|
||
for p := record.Front(); p != nil && flag <= end; p, flag = p.Next(), flag+1 {
|
||
if flag >= start {
|
||
result = append(result, p.Value)
|
||
}
|
||
}
|
||
} else {
|
||
flag := length - 1
|
||
for p := record.Back(); p != nil && flag >= start; p, flag = p.Prev(), flag-1 {
|
||
if flag <= end {
|
||
result = append(result, p.Value)
|
||
}
|
||
}
|
||
if len(result) > 0 {
|
||
for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
|
||
result[i], result[j] = result[j], result[i]
|
||
}
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// Range 遍历start到end之间的数据
|
||
func (hl *HashList) Range(key interface{}, start, end int) (result []interface{}) {
|
||
hl.mu.Lock()
|
||
defer hl.mu.Unlock()
|
||
|
||
record := hl.data[key]
|
||
if record == nil || record.Len() == 0 {
|
||
return nil
|
||
}
|
||
length := record.Len()
|
||
start, end = handleIndex(length, start, end)
|
||
if start > end || start >= length {
|
||
return nil
|
||
}
|
||
|
||
mid := length >> 1
|
||
if end <= mid || end-mid < mid-start {
|
||
flag := 0
|
||
for p := record.Front(); p != nil && flag <= end; p, flag = p.Next(), flag+1 {
|
||
if flag >= start {
|
||
result = append(result, p.Value)
|
||
}
|
||
}
|
||
} else {
|
||
flag := length - 1
|
||
for p := record.Back(); p != nil && flag >= start; p, flag = p.Prev(), flag-1 {
|
||
if flag <= end {
|
||
result = append(result, p.Value)
|
||
}
|
||
}
|
||
if len(result) > 0 {
|
||
for i, j := 0, len(result)-1; i < j; i, j = i+1, j-1 {
|
||
result[i], result[j] = result[j], result[i]
|
||
}
|
||
}
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
// Trim 截断
|
||
func (hl *HashList) Trim(key interface{}, start, end int) bool {
|
||
hl.mu.Lock()
|
||
defer hl.mu.Unlock()
|
||
|
||
record := hl.data[key]
|
||
if record == nil || record.Len() <= 0 {
|
||
return false
|
||
}
|
||
|
||
length := record.Len()
|
||
start, end = handleIndex(length, start, end)
|
||
|
||
//start小于等于左边界,end大于等于右边界,不处理
|
||
if start <= 0 && end >= length-1 {
|
||
return false
|
||
}
|
||
|
||
//start大于end,或者start超出右边界,则直接将列表置空
|
||
if start > end || start >= length {
|
||
hl.data[key] = nil
|
||
delete(hl.data, key)
|
||
return true
|
||
}
|
||
|
||
startEle, endEle := index(record, start), index(record, end)
|
||
switch end-start+1 < (length >> 1) {
|
||
case true:
|
||
newList := list.New()
|
||
for p := startEle; p != endEle.Next(); p = p.Next() {
|
||
newList.PushBack(p.Value)
|
||
}
|
||
hl.data[key] = newList
|
||
default:
|
||
var ele []*list.Element
|
||
for p := record.Front(); p != startEle; p = p.Next() {
|
||
ele = append(ele, p)
|
||
}
|
||
for p := record.Back(); p != endEle; p = p.Prev() {
|
||
ele = append(ele, p)
|
||
}
|
||
for _, e := range ele {
|
||
record.Remove(e)
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
func (hl *HashList) Len(key interface{}) (length int) {
|
||
hl.mu.RLock()
|
||
length = hl.data[key].Len()
|
||
hl.mu.RUnlock()
|
||
return
|
||
}
|
||
|
||
func (hl *HashList) push(front bool, key interface{}, val ...interface{}) int {
|
||
record := hl.data[key]
|
||
if record == nil {
|
||
record = list.New()
|
||
hl.data[key] = record
|
||
}
|
||
|
||
switch {
|
||
case front == true:
|
||
for _, v := range val {
|
||
record.PushFront(v)
|
||
}
|
||
default:
|
||
for _, v := range val {
|
||
record.PushBack(v)
|
||
}
|
||
}
|
||
return record.Len()
|
||
}
|
||
|
||
func (hl *HashList) pop(front bool, key interface{}) interface{} {
|
||
record := hl.data[key]
|
||
if record == nil || record.Len() == 0 {
|
||
return nil
|
||
}
|
||
var element *list.Element
|
||
switch {
|
||
case front:
|
||
element = record.Front()
|
||
default:
|
||
element = record.Back()
|
||
}
|
||
record.Remove(element)
|
||
return element.Value
|
||
}
|
||
|
||
func handleIndex(length, start, end int) (int, int) {
|
||
if start < 0 {
|
||
start += length
|
||
}
|
||
if end < 0 {
|
||
end += length
|
||
}
|
||
if start < 0 {
|
||
start = 0
|
||
}
|
||
if end >= length {
|
||
end = length - 1
|
||
}
|
||
return start, end
|
||
}
|
||
|
||
func validIndex(dataList *list.List, index int) (bool, int) {
|
||
if dataList == nil || dataList.Len() <= 0 {
|
||
return false, index
|
||
}
|
||
n := dataList.Len()
|
||
if index < 0 {
|
||
index += n
|
||
}
|
||
return index >= 0 && index < n, index
|
||
}
|
||
|
||
func find(dataList *list.List, target interface{}) (result *list.Element) {
|
||
if dataList == nil || dataList.Len() == 0 {
|
||
return
|
||
}
|
||
for ele := dataList.Front(); ele != nil; ele = ele.Next() {
|
||
if reflect.DeepEqual(ele.Value, target) {
|
||
result = ele
|
||
break
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
func index(dataList *list.List, index int) (data *list.Element) {
|
||
if dataList == nil || dataList.Len() == 0 {
|
||
return
|
||
}
|
||
ok, newIndex := validIndex(dataList, index)
|
||
if !ok {
|
||
return
|
||
}
|
||
index = newIndex
|
||
|
||
var element *list.Element
|
||
// 如果index在前半段,则从头开始找,否则从后半段查找
|
||
switch index <= ((dataList.Len()) >> 1) {
|
||
case true:
|
||
val := dataList.Front()
|
||
for i := 0; i < index; i++ {
|
||
val = val.Next()
|
||
}
|
||
element = val
|
||
default:
|
||
val := dataList.Back()
|
||
for i := dataList.Len() - 1; i > index; i-- {
|
||
val = val.Prev()
|
||
}
|
||
element = val
|
||
}
|
||
return element
|
||
}
|