44import java .net .Inet4Address ;
55import java .net .InetAddress ;
66import java .nio .ByteBuffer ;
7- import java .util .ArrayList ;
7+ import java .util .Stack ;
88import java .util .Arrays ;
99import java .util .Iterator ;
1010
1616 */
1717public class Networks <T > implements Iterator <DatabaseRecord <T >> {
1818 private final Reader reader ;
19- private final ArrayList <NetworkNode > nodes ;
19+ private final Stack <NetworkNode > nodes ;
2020 private NetworkNode lastNode ;
2121 private final boolean skipAliasedNetworks ;
2222 private final ByteBuffer buffer ; /* Stores the buffer for Next() calls */
@@ -44,8 +44,11 @@ public class Networks<T> implements Iterator<DatabaseRecord<T>> {
4444 throws ClosedDatabaseException {
4545 this .reader = reader ;
4646 this .skipAliasedNetworks = skipAliasedNetworks ;
47- this .nodes = new ArrayList <NetworkNode >(Arrays .asList (nodes ));
4847 this .buffer = reader .getBufferHolder ().get ();
48+ this .nodes = new Stack <NetworkNode >();
49+ for (NetworkNode node : nodes ) {
50+ this .nodes .push (node );
51+ }
4952 }
5053
5154 /**
@@ -65,7 +68,7 @@ public void setDataClass(Class<T> cls) {
6568 }
6669
6770 /**
68- * Returns the next NetworksItem . You need to set the class using
71+ * Returns the next DataRecord . You need to set the class using
6972 * prepareForClass before calling next.
7073 * For example,
7174 * networks.prepareForClass(Map.Class);
@@ -92,9 +95,13 @@ public DatabaseRecord<T> next() {
9295 // If the ip is in ipv6 form, drop the prefix manually
9396 // as InetAddress converts it to ipv4.
9497 InetAddress ipAddr = InetAddress .getByAddress (ip );
95- if (ipAddr instanceof Inet4Address && ip .length > 4
96- && ip [10 ] == -1 && ip [11 ] == -1 && prefixLength > 32 ) {
98+ if (ipAddr instanceof Inet4Address && ip .length > 4 && prefixLength > 96 ) {
9799 prefixLength -= 96 ;
100+
101+ // This is just as a safety check. This should never happen.
102+ if (prefixLength < 0 ){
103+ throw new NetworksIterationException ("A network" + ip +" has an invalid prefix length of " + prefixLength );
104+ }
98105 }
99106
100107 return new DatabaseRecord <T >(data , InetAddress .getByAddress (ip ), prefixLength );
@@ -123,8 +130,7 @@ public boolean isInIpv4Subtree(byte[] ip) {
123130 @ Override
124131 public boolean hasNext () {
125132 while (!this .nodes .isEmpty ()) {
126- // Pop the last one.
127- NetworkNode node = this .nodes .remove (this .nodes .size () - 1 );
133+ NetworkNode node = this .nodes .pop ();
128134
129135 // Next until we don't have data.
130136 while (node .pointer != this .reader .getMetadata ().getNodeCount ()) {
@@ -152,7 +158,7 @@ public boolean hasNext() {
152158 int rightPointer = this .reader .readNode (this .buffer , node .pointer , 1 );
153159 node .prefix ++;
154160
155- this .nodes .add (new NetworkNode (ipRight , node .prefix , rightPointer ));
161+ this .nodes .push (new NetworkNode (ipRight , node .prefix , rightPointer ));
156162 node .pointer = this .reader .readNode (this .buffer , node .pointer , 0 );
157163 } catch (InvalidDatabaseException e ) {
158164 throw new NetworksIterationException (e .getMessage ());
0 commit comments