code: func (s *ticketStore) nextRegisterableTicket() (*ticketRef, time.Duration) {
  	now := mclock.Now()
  	if s.nextTicketCached != nil {
  		return s.nextTicketCached, time.Duration(s.nextTicketCached.topicRegTime() - now)
  	}
  
  	for bucket := s.lastBucketFetched; ; bucket++ {
  		var (
  			empty      = true    // true if there are no tickets
  			nextTicket ticketRef // uninitialized if this bucket is empty
  		)
  		for _, tickets := range s.tickets {
  			//s.removeExcessTickets(topic)
  			if len(tickets.buckets) != 0 {
  				empty = false
  
  				list := tickets.buckets[bucket]
  				for _, ref := range list {
  					//debugLog(fmt.Sprintf(" nrt bucket = %d node = %x sn = %v wait = %v", bucket, ref.t.node.ID[:8], ref.t.serial, time.Duration(ref.topicRegTime()-now)))
  					if nextTicket.t == nil || ref.topicRegTime() < nextTicket.topicRegTime() {
  						nextTicket = ref
  					}
  				}
  			}
  		}
  		if empty {
  			return nil, 0
  		}
  		if nextTicket.t != nil {
  			s.nextTicketCached = &nextTicket
  			return &nextTicket, time.Duration(nextTicket.topicRegTime() - now)
  		}
  		s.lastBucketFetched = bucket
  	}
  }
docs: // nextRegisterableTicket returns the next ticket that can be used
  // to register.
  //
  // If the returned wait time <= zero the ticket can be used. For a positive
  // wait time, the caller should requery the next ticket later.
  //
  // A ticket can be returned more than once with <= zero wait time in case
  // the ticket contains multiple topics.