| 148 | } |
| 149 | |
| 150 | bool redis_builder::create_cluster(acl::xml& xml, size_t replicas) |
| 151 | { |
| 152 | const char* tag = "node"; |
| 153 | const std::vector<acl::xml_node*>& nodes = xml.getElementsByTagName(tag); |
| 154 | |
| 155 | if (nodes.empty()) { |
| 156 | printf("%s: nodes null\r\n", __FUNCTION__); |
| 157 | return false; |
| 158 | } |
| 159 | |
| 160 | std::vector<acl::redis_node*> redis_nodes; |
| 161 | |
| 162 | std::vector<acl::xml_node*>::const_iterator cit; |
| 163 | for (cit = nodes.begin(); cit != nodes.end(); ++cit) { |
| 164 | acl::redis_node* n = create_node(**cit); |
| 165 | if (n != NULL) { |
| 166 | redis_nodes.push_back(n); |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | size_t mod = redis_nodes.size() % (replicas + 1); |
| 171 | if (replicas > 0 && mod != 0) { |
| 172 | printf("%s: nodes' size(%d) %% replicas + 1(%d) is %d != 0\r\n", |
| 173 | __FUNCTION__, (int) redis_nodes.size(), |
| 174 | (int) replicas + 1, (int) mod); |
| 175 | std::vector<acl::redis_node*>::iterator it; |
| 176 | for (it = redis_nodes.begin(); it != redis_nodes.end(); ++it) { |
| 177 | delete *it; |
| 178 | } |
| 179 | return false; |
| 180 | } |
| 181 | |
| 182 | std::map<acl::string, size_t> master_addrs; |
| 183 | std::map<acl::string, size_t> all_addrs; |
| 184 | acl::redis_node* master, *slave; |
| 185 | acl::string ip; |
| 186 | while (true) { |
| 187 | master = peek_master(redis_nodes, master_addrs); |
| 188 | if (master == NULL) { |
| 189 | break; |
| 190 | } |
| 191 | masters_.push_back(master); |
| 192 | |
| 193 | assert(redis_util::get_ip(master->get_addr(), ip)); |
| 194 | all_addrs[ip]++; |
| 195 | |
| 196 | for (size_t i = 0; i < replicas; i++) { |
| 197 | slave = peek_slave(master->get_addr(), |
| 198 | redis_nodes, all_addrs); |
| 199 | if (slave != NULL) { |
| 200 | master->add_slave(slave); |
| 201 | } |
| 202 | } |
| 203 | } |
| 204 | |
| 205 | return true; |
| 206 | } |
| 207 | |