liwnn / zset

This Go package provides an implementation of sorted set in redis

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ZSet

This Go package provides an implementation of sorted set in redis.

Usage (go < 1.18)

All you have to do is to implement a comparison function Less(Item) bool and a function Key() string for your Item which will be store in the zset, here are some examples.

package main

import (
	"fmt"

	"github.com/liwnn/zset"
)

type User struct {
	Name  string
	Score int
}

func (u User) Key() string {
	return u.Name
}

func (u User) Less(than zset.Item) bool {
	if u.Score == than.(User).Score {
		return u.Name < than.(User).Name
	}
	return u.Score < than.(User).Score
}

func main() {
	zs := zset.New()

	// Add
	zs.Add("Hurst", User{Name: "Hurst", Score: 88})
	zs.Add("Peek", User{Name: "Peek", Score: 100})
	zs.Add("Beaty", User{Name: "Beaty", Score: 66})

	// Rank
	rank := zs.Rank("Hurst", true)
	fmt.Printf("Hurst's rank is %v\n", rank) // expected 2

	// Range
	fmt.Println()
	fmt.Println("Range[0,3]:")
	zs.Range(0, 3, true, func(v zset.Item, rank int) bool {
		fmt.Printf("%v's rank is %v\n", v.(User).Key(), rank)
		return true
	})

	// Range with Iterator
	fmt.Println()
	fmt.Println("Range[0,3] with Iterator:")
	for it := zs.RangeIterator(0, 3, true); it.Valid(); it.Next() {
		fmt.Printf("Ite: %v's rank is %v\n", it.Item().(User).Key(), it.Rank())
	}

	// Range by score [88, 100]
	fmt.Println()
	fmt.Println("RangeByScore[88,100]:")
	zs.RangeByScore(func(i zset.Item) bool {
		return i.(User).Score >= 88
	}, func(i zset.Item) bool {
		return i.(User).Score <= 100
	}, true, func(i zset.Item, rank int) bool {
		fmt.Printf("%v's score[%v] rank is %v\n", i.(User).Key(), i.(User).Score, rank)
		return true
	})

	// Remove
	zs.Remove("Peek")

	// Rank
	fmt.Println()
	fmt.Println("After remove Peek:")
	rank = zs.Rank("Hurst", true)
	fmt.Printf("Hurst's rank is %v\n", rank) // expected 1
}

Output:

Hurst's rank is 2

Range[0,3]:
Peek's rank is 1
Hurst's rank is 2
Beaty's rank is 3

Range[0,3] with Iterator:
Ite: Peek's rank is 1
Ite: Hurst's rank is 2
Ite: Beaty's rank is 3

RangeByScore[88,100]:
Peek's score[100] rank is 1
Hurst's score[88] rank is 2

After remove Peek:
Hurst's rank is 1

Usage (go >= 1.18)

package main

import (
	"fmt"

	"github.com/liwnn/zset"
)

type User struct {
	Name  string
	Score int
}

func (u User) Key() string {
	return u.Name
}

func (u User) Less(than User) bool {
	if u.Score == than.Score {
		return u.Name < than.Name
	}
	return u.Score < than.Score
}

func main() {
	zs := zset.New[string, User](func(a, b User) bool {
		return a.Less(b)
	})

	// Add
	zs.Add("Hurst", User{Name: "Hurst", Score: 88})
	zs.Add("Peek", User{Name: "Peek", Score: 100})
	zs.Add("Beaty", User{Name: "Beaty", Score: 66})

	// Rank
	rank := zs.Rank("Hurst", true)
	fmt.Printf("Hurst's rank is %v\n", rank) // expected 2

	// Range
	fmt.Println()
	fmt.Println("Range[0,3]:")
	zs.Range(0, 3, true, func(v User, rank int) bool {
		fmt.Printf("%v's rank is %v\n", v.Key(), rank)
		return true
	})

	// Range with Iterator
	fmt.Println()
	fmt.Println("Range[0,3] with Iterator:")
	for it := zs.RangeIterator(0, 3, true); it.Valid(); it.Next() {
		fmt.Printf("Ite: %v's rank is %v\n", it.Item().Key(), it.Rank())
	}

	// Range by score [88, 100]
	fmt.Println()
	fmt.Println("RangeByScore[88,100]:")
	zs.RangeByScore(func(i User) bool {
		return i.Score >= 88
	}, func(i User) bool {
		return i.Score <= 100
	}, true, func(i User, rank int) bool {
		fmt.Printf("%v's score[%v] rank is %v\n", i.Key(), i.Score, rank)
		return true
	})

	// Remove
	zs.Remove("Peek")

	// Rank
	fmt.Println()
	fmt.Println("After remove Peek:")
	rank = zs.Rank("Hurst", true)
	fmt.Printf("Hurst's rank is %v\n", rank) // expected 1
}

About

This Go package provides an implementation of sorted set in redis


Languages

Language:Go 100.0%