From 348fc5f33fd5818203560a041834e5a0380eee80 Mon Sep 17 00:00:00 2001 From: Peter Stuifzand Date: Sun, 2 Sep 2018 11:12:07 +0200 Subject: [PATCH] StablePartition the channels based on unread count --- cmd/eksterd/memory.go | 5 ++++ pkg/util/algorithm.go | 59 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 pkg/util/algorithm.go diff --git a/cmd/eksterd/memory.go b/cmd/eksterd/memory.go index b3a41e0..90b38a2 100644 --- a/cmd/eksterd/memory.go +++ b/cmd/eksterd/memory.go @@ -34,6 +34,7 @@ import ( "p83.nl/go/ekster/pkg/fetch" "p83.nl/go/ekster/pkg/microsub" + "p83.nl/go/ekster/pkg/util" "github.com/gomodule/redigo/redis" "willnorris.com/go/microformats" @@ -185,6 +186,10 @@ func (b *memoryBackend) ChannelsGetList() ([]microsub.Channel, error) { } } } + util.StablePartition(channels, 0, len(channels), func(i int) bool { + return channels[i].Unread > 0 + }) + return channels, nil } diff --git a/pkg/util/algorithm.go b/pkg/util/algorithm.go new file mode 100644 index 0000000..b409518 --- /dev/null +++ b/pkg/util/algorithm.go @@ -0,0 +1,59 @@ +package util + +import "reflect" + +func Rotate(a interface{}, f, k, l int) int { + swapper := reflect.Swapper(a) + if f == k { + return l + } + if k == l { + return f + } + next := k + + for { + swapper(f, next) + f++ + next++ + if f == k { + k = next + } + if next == l { + break + } + } + + ret := f + for next = k; next != l; { + swapper(f, next) + f++ + next++ + if f == k { + k = next + } else if next == l { + next = k + } + } + return ret +} + +func StablePartition(a interface{}, f, l int, p func(i int) bool) int { + n := l - f + + if n == 0 { + return f + } + + if n == 1 { + t := f + if p(f) { + t += 1 + } + return t + } + + m := f + (n / 2) + + return Rotate(a, StablePartition(a, f, m, p), m, StablePartition(a, m, l, p)) +}