View Javadoc
1   /*
2    * Copyright 2015 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  
17  package io.netty.resolver.dns;
18  
19  import io.netty.util.internal.PlatformDependent;
20  
21  import java.net.InetSocketAddress;
22  import java.util.Random;
23  
24  final class ShuffledDnsServerAddressStream implements DnsServerAddressStream {
25  
26      private final InetSocketAddress[] addresses;
27      private int i;
28  
29      /**
30       * Create a new instance.
31       * @param addresses The addresses are not cloned. It is assumed the caller has cloned this array or otherwise will
32       *                  not modify the contents.
33       */
34      ShuffledDnsServerAddressStream(InetSocketAddress[] addresses) {
35          this.addresses = addresses;
36  
37          shuffle();
38      }
39  
40      private ShuffledDnsServerAddressStream(InetSocketAddress[] addresses, int startIdx) {
41          this.addresses = addresses;
42          i = startIdx;
43      }
44  
45      private void shuffle() {
46          final InetSocketAddress[] addresses = this.addresses;
47          final Random r = PlatformDependent.threadLocalRandom();
48  
49          for (int i = addresses.length - 1; i >= 0; i --) {
50              InetSocketAddress tmp = addresses[i];
51              int j = r.nextInt(i + 1);
52              addresses[i] = addresses[j];
53              addresses[j] = tmp;
54          }
55      }
56  
57      @Override
58      public InetSocketAddress next() {
59          int i = this.i;
60          InetSocketAddress next = addresses[i];
61          if (++ i < addresses.length) {
62              this.i = i;
63          } else {
64              this.i = 0;
65              shuffle();
66          }
67          return next;
68      }
69  
70      @Override
71      public int size() {
72          return addresses.length;
73      }
74  
75      @Override
76      public ShuffledDnsServerAddressStream duplicate() {
77          return new ShuffledDnsServerAddressStream(addresses, i);
78      }
79  
80      @Override
81      public String toString() {
82          return SequentialDnsServerAddressStream.toString("shuffled", i, addresses);
83      }
84  }