// GetStoreList returns a storeList that contains all active stores that // contain the required attributes and their associated stats. It also returns // the number of total alive stores. // TODO(embark, spencer): consider using a reverse index map from // Attr->stores, for efficiency. Ensure that entries in this map still // have an opportunity to be garbage collected. func (sp *StorePool) getStoreList(required roachpb.Attributes, deterministic bool) (StoreList, int) { sp.mu.RLock() defer sp.mu.RUnlock() var storeIDs roachpb.StoreIDSlice for storeID := range sp.stores { storeIDs = append(storeIDs, storeID) } // Sort the stores by key if deterministic is requested. This is only for // unit testing. if deterministic { sort.Sort(storeIDs) } sl := StoreList{} var aliveStoreCount int for _, storeID := range storeIDs { detail := sp.stores[roachpb.StoreID(storeID)] if !detail.dead && detail.desc != nil { aliveStoreCount++ if required.IsSubset(*detail.desc.CombinedAttrs()) { sl.add(detail.desc) } } } return sl, aliveStoreCount }
// GetStoreList returns a storeList that contains all active stores that // contain the required attributes and their associated stats. // TODO(embark, spencer): consider using a reverse index map from // Attr->stores, for efficiency. Ensure that entries in this map still // have an opportunity to be garbage collected. func (sp *StorePool) getStoreList(required roachpb.Attributes, excludeNodes []roachpb.NodeID, deterministic bool) StoreList { sp.mu.RLock() defer sp.mu.RUnlock() // Convert list of excluded nodes to a map for quick lookup. excludeMap := map[roachpb.NodeID]struct{}{} for _, nodeID := range excludeNodes { excludeMap[nodeID] = struct{}{} } var storeIDs roachpb.StoreIDSlice for storeID := range sp.stores { storeIDs = append(storeIDs, storeID) } // Sort the stores by key if deterministic is requested. This is only for // unit testing. if deterministic { sort.Sort(storeIDs) } sl := StoreList{} for _, storeID := range storeIDs { detail := sp.stores[roachpb.StoreID(storeID)] if _, ok := excludeMap[detail.desc.Node.NodeID]; ok { continue } if !detail.dead && required.IsSubset(*detail.desc.CombinedAttrs()) { desc := detail.desc sl.add(&desc) } } return sl }
// match returns if the store is alive, and if the store is available and it's // attributes contain the required ones respectively. func (sd *storeDetail) match(now time.Time, required roachpb.Attributes) storeMatch { // The store must be alive and it must have a descriptor to be considered // alive. if sd.dead || sd.desc == nil { return storeMatchDead } // The store must not have a recent declined reservation to be considered // available for matching. if sd.unavailableUntil.After(now) || !required.IsSubset(*sd.desc.CombinedAttrs()) { return storeMatchAlive } return storeMatchMatched }
// match checks the store against the attributes and returns a storeMatch. func (sd *storeDetail) match(now time.Time, required roachpb.Attributes) storeMatch { // The store must be alive and it must have a descriptor to be considered // alive. if sd.dead || sd.desc == nil { return storeMatchDead } // Does the store match the attributes? if !required.IsSubset(*sd.desc.CombinedAttrs()) { return storeMatchAlive } // The store must not have a recent declined reservation to be available. if sd.throttledUntil.After(now) { return storeMatchThrottled } return storeMatchAvailable }
// GetStoreList returns a storeList that contains all active stores that // contain the required attributes and their associated stats. // TODO(embark, spencer): consider using a reverse index map from // Attr->stores, for efficiency. Ensure that entries in this map still // have an opportunity to be garbage collected. func (sp *StorePool) getStoreList(required roachpb.Attributes, deterministic bool) *StoreList { sp.mu.RLock() defer sp.mu.RUnlock() var storeIDs roachpb.StoreIDSlice for storeID := range sp.stores { storeIDs = append(storeIDs, storeID) } // Sort the stores by key if deterministic is requested. This is only for // unit testing. if deterministic { sort.Sort(storeIDs) } sl := new(StoreList) for _, storeID := range storeIDs { detail := sp.stores[roachpb.StoreID(storeID)] if !detail.dead && required.IsSubset(*detail.desc.CombinedAttrs()) { desc := detail.desc sl.add(&desc) } } return sl }