func (c *Collection) Find(cursor string, limit int) ([]*linkedca.Admin, string) {
	switch {
	case limit <= 0:
		limit = DefaultAdminLimit
	case limit > DefaultAdminMax:
		limit = DefaultAdminMax
	}
	n := c.sorted.Len()
	i := sort.Search(n, func(i int) bool { return c.sorted[i].Id >= cursor })
	slice := []*linkedca.Admin{}
	for ; i < n && len(slice) < limit; i++ {
		slice = append(slice, c.sorted[i])
	}
	if i < n {
		return slice, c.sorted[i].Id
	}
	return slice, ""
}
Find implements pagination on a list of sorted admins.
package administrator
import (
	"sort"
	"sync"
	"github.com/pkg/errors"
	"github.com/smallstep/certificates/authority/admin"
	"github.com/smallstep/certificates/authority/provisioner"
	"go.step.sm/linkedca"
)
const DefaultAdminLimit = 20
const DefaultAdminMax = 100
type adminSlice []*linkedca.Admin
func (p adminSlice) Len() int           { return len(p) }
func (p adminSlice) Less(i, j int) bool { return p[i].Id < p[j].Id }
func (p adminSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
type Collection struct {
	byID                    *sync.Map
	bySubProv               *sync.Map
	byProv                  *sync.Map
	sorted                  adminSlice
	provisioners            *provisioner.Collection
	superCount              int
	superCountByProvisioner map[string]int
}
func NewCollection(provisioners *provisioner.Collection) *Collection {
	return &Collection{
		byID:                    new(sync.Map),
		byProv:                  new(sync.Map),
		bySubProv:               new(sync.Map),
		superCountByProvisioner: map[string]int{},
		provisioners:            provisioners,
	}
}
func (c *Collection) LoadByID(id string) (*linkedca.Admin, bool) {
	return loadAdmin(c.byID, id)
}
type subProv struct {
	subject     string
	provisioner string
}
func newSubProv(subject, prov string) subProv {
	return subProv{subject, prov}
}
func (c *Collection) LoadBySubProv(sub, provName string) (*linkedca.Admin, bool) {
	return loadAdmin(c.bySubProv, newSubProv(sub, provName))
}
func (c *Collection) LoadByProvisioner(provName string) ([]*linkedca.Admin, bool) {
	val, ok := c.byProv.Load(provName)
	if !ok {
		return nil, false
	}
	admins, ok := val.([]*linkedca.Admin)
	if !ok {
		return nil, false
	}
	return admins, true
}
func (c *Collection) Store(adm *linkedca.Admin, prov provisioner.Interface) error {
	if adm.ProvisionerId != prov.GetID() {
		return admin.NewErrorISE("admin.provisionerId does not match provisioner argument")
	}
	if _, loaded := c.byID.LoadOrStore(adm.Id, adm); loaded {
		return errors.New("cannot add multiple admins with the same id")
	}
	provName := prov.GetName()
	if _, loaded := c.bySubProv.LoadOrStore(newSubProv(adm.Subject, provName), adm); loaded {
		c.byID.Delete(adm.Id)
		return errors.New("cannot add multiple admins with the same subject and provisioner")
	}
	var isSuper = (adm.Type == linkedca.Admin_SUPER_ADMIN)
	if admins, ok := c.LoadByProvisioner(provName); ok {
		c.byProv.Store(provName, append(admins, adm))
		if isSuper {
			c.superCountByProvisioner[provName]++
		}
	} else {
		c.byProv.Store(provName, []*linkedca.Admin{adm})
		if isSuper {
			c.superCountByProvisioner[provName] = 1
		}
	}
	if isSuper {
		c.superCount++
	}
	c.sorted = append(c.sorted, adm)
	sort.Sort(c.sorted)
	return nil
}
func (c *Collection) Remove(id string) error {
	adm, ok := c.LoadByID(id)
	if !ok {
		return admin.NewError(admin.ErrorNotFoundType, "admin %s not found", id)
	}
	if adm.Type == linkedca.Admin_SUPER_ADMIN && c.SuperCount() == 1 {
		return admin.NewError(admin.ErrorBadRequestType, "cannot remove the last super admin")
	}
	prov, ok := c.provisioners.Load(adm.ProvisionerId)
	if !ok {
		return admin.NewError(admin.ErrorNotFoundType,
			"provisioner %s for admin %s not found", adm.ProvisionerId, id)
	}
	provName := prov.GetName()
	adminsByProv, ok := c.LoadByProvisioner(provName)
	if !ok {
		return admin.NewError(admin.ErrorNotFoundType,
			"admins not found for provisioner %s", provName)
	}
	sortedIndex := sort.Search(c.sorted.Len(), func(i int) bool { return c.sorted[i].Id >= adm.Id })
	if c.sorted[sortedIndex].Id != adm.Id {
		return admin.NewError(admin.ErrorNotFoundType,
			"admin %s not found in sorted list", adm.Id)
	}
	var found bool
	for i, a := range adminsByProv {
		if a.Id == adm.Id {
			adminsByProv[i] = adminsByProv[len(adminsByProv)-1]
			c.byProv.Store(provName, adminsByProv[:len(adminsByProv)-1])
			found = true
		}
	}
	if !found {
		return admin.NewError(admin.ErrorNotFoundType,
			"admin %s not found in adminsByProvisioner list", adm.Id)
	}
	copy(c.sorted[sortedIndex:], c.sorted[sortedIndex+1:])  
	c.sorted[len(c.sorted)-1] = nil                         
	c.sorted = c.sorted[:len(c.sorted)-1]                   
	c.byID.Delete(adm.Id)
	c.bySubProv.Delete(newSubProv(adm.Subject, provName))
	if adm.Type == linkedca.Admin_SUPER_ADMIN {
		c.superCount--
		c.superCountByProvisioner[provName]--
	}
	return nil
}
func (c *Collection) Update(id string, nu *linkedca.Admin) (*linkedca.Admin, error) {
	adm, ok := c.LoadByID(id)
	if !ok {
		return nil, admin.NewError(admin.ErrorNotFoundType, "admin %s not found", adm.Id)
	}
	if adm.Type == nu.Type {
		return adm, nil
	}
	if adm.Type == linkedca.Admin_SUPER_ADMIN && c.SuperCount() == 1 {
		return nil, admin.NewError(admin.ErrorBadRequestType, "cannot change role of last super admin")
	}
	adm.Type = nu.Type
	return adm, nil
}
func (c *Collection) SuperCount() int {
	return c.superCount
}
func (c *Collection) SuperCountByProvisioner(provName string) int {
	if cnt, ok := c.superCountByProvisioner[provName]; ok {
		return cnt
	}
	return 0
}