func (rb *routingBucket) popAndAppend(idx int, ni *nodeInfo) {
	prev := rb.bucket
	l := len(prev)
	rb.bucket = make([]*nodeInfo, l)
	for i := 0; i < l; i++ {
		if i == l-1 {
			rb.bucket[i] = ni
		} else if i < idx {
			rb.bucket[i] = prev[i]
		} else {
			rb.bucket[i] = prev[i+1]
		}
	}
}
pop item on `idx` and then append `ni`
package node
import (
	"context"
	"crypto/sha1"
	"fmt"
	"sort"
	"sync"
	"time"
	"github.com/mathetake/doogle/crawler"
	"github.com/mathetake/doogle/grpc"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"golang.org/x/crypto/ed25519"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)
const (
	alpha         = 3
	bucketSize    = 20
	maxNumGetItem = 20  
)
type item struct {
	dAddrStr doogleAddressStr
	url   string
	title string
	edges []doogleAddressStr
	localRank         float64
	rankComputedCount float64
	mux sync.Mutex
}
type Node struct {
	DAddr doogleAddress
	routingTable map[int]*routingBucket
	dht sync.Map
	items sync.Map
	publicKey  []byte
	secretKey  []byte
	nonce      []byte
	difficulty int
	certificate *doogle.NodeCertificate
	logger *logrus.Logger
	crawler crawler.Crawler
	nAddrToConn sync.Map
	pageRankComputingQueue chan doogleAddressStr
}
var _ doogle.DoogleServer = &Node{}
type nodeInfo struct {
	dAddr      doogleAddress
	nAddr      string
	accessedAt int64
}
type routingBucket struct {
	bucket []*nodeInfo
	mux    sync.Mutex
}