QueryPlan* TokenAwarePolicy::new_query_plan(const std::string& connected_keyspace, const Request* request, const TokenMap* token_map, Request::EncodingCache* cache) { if (request != NULL) { switch (request->opcode()) { { case CQL_OPCODE_QUERY: case CQL_OPCODE_EXECUTE: case CQL_OPCODE_BATCH: const RoutableRequest* rr = static_cast<const RoutableRequest*>(request); const std::string& statement_keyspace = rr->keyspace(); const std::string& keyspace = statement_keyspace.empty() ? connected_keyspace : statement_keyspace; std::string routing_key; if (rr->get_routing_key(&routing_key, cache) && !keyspace.empty()) { if (token_map != NULL) { CopyOnWriteHostVec replicas = token_map->get_replicas(keyspace, routing_key); if (replicas && !replicas->empty()) { return new TokenAwareQueryPlan(child_policy_.get(), child_policy_->new_query_plan(connected_keyspace, request, token_map, cache), replicas, index_++); } } } break; } default: break; } } return child_policy_->new_query_plan(connected_keyspace, request, token_map, cache); }
// The number of replicas is bounded by replication factor per DC. In practice, the number // of replicas is fairly small so a linear search should be extremely fast. static inline bool contains(const CopyOnWriteHostVec& replicas, const Address& address) { for (HostVec::const_iterator i = replicas->begin(), end = replicas->end(); i != end; ++i) { if ((*i)->address() == address) { return true; } } return false; }
TokenAwareQueryPlan(LoadBalancingPolicy* child_policy, QueryPlan* child_plan, const CopyOnWriteHostVec& replicas, size_t start_index) : child_policy_(child_policy) , child_plan_(child_plan) , replicas_(replicas) , index_(start_index) , remaining_(replicas->size()) {}
RoundRobinQueryPlan(const CopyOnWriteHostVec& hosts, size_t start_index) : hosts_(hosts) , index_(start_index) , remaining_(hosts->size()) { }
// Helper method to prevent copy (Notice: "const CopyOnWriteHostVec&") static size_t get_hosts_size(const CopyOnWriteHostVec& hosts) { return hosts->size(); }