aboutsummaryrefslogtreecommitdiffstats
path: root/common/prque/prque.go
diff options
context:
space:
mode:
authorFelföldi Zsolt <zsfelfoldi@gmail.com>2018-08-15 04:44:46 +0800
committerFelix Lange <fjl@users.noreply.github.com>2018-08-15 04:44:46 +0800
commitb2ddb1fcbf77771d0693ee5a00f8ae1cd4c0f87c (patch)
treecc70e50a0aa168afdda0a7737996686ca836621b /common/prque/prque.go
parenta1783d169732dd34aa8c7d68f411ce741c1a5015 (diff)
downloaddexon-b2ddb1fcbf77771d0693ee5a00f8ae1cd4c0f87c.tar
dexon-b2ddb1fcbf77771d0693ee5a00f8ae1cd4c0f87c.tar.gz
dexon-b2ddb1fcbf77771d0693ee5a00f8ae1cd4c0f87c.tar.bz2
dexon-b2ddb1fcbf77771d0693ee5a00f8ae1cd4c0f87c.tar.lz
dexon-b2ddb1fcbf77771d0693ee5a00f8ae1cd4c0f87c.tar.xz
dexon-b2ddb1fcbf77771d0693ee5a00f8ae1cd4c0f87c.tar.zst
dexon-b2ddb1fcbf77771d0693ee5a00f8ae1cd4c0f87c.zip
les: implement client connection logic (#16899)
This PR implements les.freeClientPool. It also adds a simulated clock in common/mclock, which enables time-sensitive tests to run quickly and still produce accurate results, and package common/prque which is a generalised variant of prque that enables removing elements other than the top one from the queue. les.freeClientPool implements a client database that limits the connection time of each client and manages accepting/rejecting incoming connections and even kicking out some connected clients. The pool calculates recent usage time for each known client (a value that increases linearly when the client is connected and decreases exponentially when not connected). Clients with lower recent usage are preferred, unknown nodes have the highest priority. Already connected nodes receive a small bias in their favor in order to avoid accepting and instantly kicking out clients. Note: the pool can use any string for client identification. Using signature keys for that purpose would not make sense when being known has a negative value for the client. Currently the LES protocol manager uses IP addresses (without port address) to identify clients.
Diffstat (limited to 'common/prque/prque.go')
-rwxr-xr-xcommon/prque/prque.go57
1 files changed, 57 insertions, 0 deletions
diff --git a/common/prque/prque.go b/common/prque/prque.go
new file mode 100755
index 000000000..9fd31a2e5
--- /dev/null
+++ b/common/prque/prque.go
@@ -0,0 +1,57 @@
+// This is a duplicated and slightly modified version of "gopkg.in/karalabe/cookiejar.v2/collections/prque".
+
+package prque
+
+import (
+ "container/heap"
+)
+
+// Priority queue data structure.
+type Prque struct {
+ cont *sstack
+}
+
+// Creates a new priority queue.
+func New(setIndex setIndexCallback) *Prque {
+ return &Prque{newSstack(setIndex)}
+}
+
+// Pushes a value with a given priority into the queue, expanding if necessary.
+func (p *Prque) Push(data interface{}, priority int64) {
+ heap.Push(p.cont, &item{data, priority})
+}
+
+// Pops the value with the greates priority off the stack and returns it.
+// Currently no shrinking is done.
+func (p *Prque) Pop() (interface{}, int64) {
+ item := heap.Pop(p.cont).(*item)
+ return item.value, item.priority
+}
+
+// Pops only the item from the queue, dropping the associated priority value.
+func (p *Prque) PopItem() interface{} {
+ return heap.Pop(p.cont).(*item).value
+}
+
+// Remove removes the element with the given index.
+func (p *Prque) Remove(i int) interface{} {
+ if i < 0 {
+ return nil
+ }
+ return heap.Remove(p.cont, i)
+}
+
+// Checks whether the priority queue is empty.
+func (p *Prque) Empty() bool {
+ return p.cont.Len() == 0
+}
+
+// Returns the number of element in the priority queue.
+func (p *Prque) Size() int {
+ return p.cont.Len()
+}
+
+// Clears the contents of the priority queue.
+func (p *Prque) Reset() {
+ *p = *New(p.cont.setIndex)
+}