diff --git a/nomad/state/schema.go b/nomad/state/schema.go index 434ad733b..4a0064fd9 100644 --- a/nomad/state/schema.go +++ b/nomad/state/schema.go @@ -69,28 +69,6 @@ func nodeTableSchema() *memdb.TableSchema { Lowercase: true, }, }, - - // DC status is a compound index on both the - // datacenter and the node status. This allows - // us to filter to a set of eligible nodes more - // quickly for selection. - "dc-status": &memdb.IndexSchema{ - Name: "dc-status", - AllowMissing: false, - Unique: false, - Indexer: &memdb.CompoundIndex{ - AllowMissing: false, - Indexes: []memdb.Indexer{ - &memdb.StringFieldIndex{ - Field: "Datacenter", - Lowercase: true, - }, - &memdb.StringFieldIndex{ - Field: "Status", - }, - }, - }, - }, }, } } diff --git a/nomad/state/state_store.go b/nomad/state/state_store.go index e20ac23e0..b1042dbab 100644 --- a/nomad/state/state_store.go +++ b/nomad/state/state_store.go @@ -207,18 +207,6 @@ func (s *StateStore) Nodes() (memdb.ResultIterator, error) { return iter, nil } -// Nodes returns an iterator over all the nodes in a DC with a given status -func (s *StateStore) NodesByDatacenterStatus(dc, status string) (memdb.ResultIterator, error) { - txn := s.db.Txn(false) - - // Walk the nodes table, filtering on DC and Status - iter, err := txn.Get("nodes", "dc-status", dc, status) - if err != nil { - return nil, err - } - return iter, nil -} - // RegisterJob is used to register a job or update a job definition func (s *StateStore) RegisterJob(index uint64, job *structs.Job) error { txn := s.db.Txn(true) diff --git a/nomad/state/state_store_test.go b/nomad/state/state_store_test.go index 01ac7a074..4b521eaee 100644 --- a/nomad/state/state_store_test.go +++ b/nomad/state/state_store_test.go @@ -151,69 +151,6 @@ func TestStateStore_Nodes(t *testing.T) { } } -func TestStateStore_NodesByDatacenterStatus(t *testing.T) { - state := testStateStore(t) - var dc1 []*structs.Node - var dc2 []*structs.Node - - for i := 0; i < 10; i++ { - node := mock.Node() - if i%2 == 0 { - node.Datacenter = "dc2" - dc2 = append(dc2, node) - } else { - dc1 = append(dc1, node) - } - - err := state.RegisterNode(1000+uint64(i), node) - if err != nil { - t.Fatalf("err: %v", err) - } - } - - iter, err := state.NodesByDatacenterStatus("dc1", structs.NodeStatusReady) - if err != nil { - t.Fatalf("err: %v", err) - } - - var out []*structs.Node - for { - raw := iter.Next() - if raw == nil { - break - } - out = append(out, raw.(*structs.Node)) - } - - sort.Sort(NodeIDSort(dc1)) - sort.Sort(NodeIDSort(out)) - - if !reflect.DeepEqual(dc1, out) { - t.Fatalf("bad: %#v %#v", dc1, out) - } - - iter, err = state.NodesByDatacenterStatus("dc2", structs.NodeStatusReady) - if err != nil { - t.Fatalf("err: %v", err) - } - - out = out[:0] - for { - raw := iter.Next() - if raw == nil { - break - } - out = append(out, raw.(*structs.Node)) - } - - sort.Sort(NodeIDSort(dc2)) - sort.Sort(NodeIDSort(out)) - - if !reflect.DeepEqual(dc2, out) { - t.Fatalf("bad: %#v %#v", dc2, out) - } -} - func TestStateStore_RestoreNode(t *testing.T) { state := testStateStore(t) diff --git a/scheduler/scheduler.go b/scheduler/scheduler.go index 8de3a9754..d831e071c 100644 --- a/scheduler/scheduler.go +++ b/scheduler/scheduler.go @@ -56,9 +56,6 @@ type State interface { // The type of each result is *structs.Node Nodes() (memdb.ResultIterator, error) - // Nodes returns an iterator over all the nodes in a DC with a given status - NodesByDatacenterStatus(dc, status string) (memdb.ResultIterator, error) - // AllocsByJob returns the allocations by JobID AllocsByJob(jobID string) ([]*structs.Allocation, error) diff --git a/scheduler/util.go b/scheduler/util.go index 689b62564..84eeaa105 100644 --- a/scheduler/util.go +++ b/scheduler/util.go @@ -117,19 +117,33 @@ func diffAllocs(job *structs.Job, taintedNodes map[string]bool, // readyNodesInDCs returns all the ready nodes in the given datacenters func readyNodesInDCs(state State, dcs []string) ([]*structs.Node, error) { - var out []*structs.Node + // Index the DCs + dcMap := make(map[string]struct{}, len(dcs)) for _, dc := range dcs { - iter, err := state.NodesByDatacenterStatus(dc, structs.NodeStatusReady) - if err != nil { - return nil, err + dcMap[dc] = struct{}{} + } + + // Scan the nodes + var out []*structs.Node + iter, err := state.Nodes() + if err != nil { + return nil, err + } + for { + raw := iter.Next() + if raw == nil { + break } - for { - raw := iter.Next() - if raw == nil { - break - } - out = append(out, raw.(*structs.Node)) + + // Filter on datacenter and status + node := raw.(*structs.Node) + if node.Status != structs.NodeStatusReady { + continue } + if _, ok := dcMap[node.Datacenter]; !ok { + continue + } + out = append(out, node) } return out, nil }