1+ import java .io .File ;
2+ import java .io .FileInputStream ;
3+ import java .io .IOException ;
4+ import java .nio .ByteBuffer ;
5+ import java .nio .ByteOrder ;
6+ import java .util .Arrays ;
7+ import java .util .concurrent .Executors ;
8+ import java .util .concurrent .TimeUnit ;
9+ import java .util .concurrent .locks .ReentrantLock ;
10+
11+ public class IPExt {
12+ public static void main (String [] args ) {
13+ IPExt .load ("H:\\ loveapp\\ codebase\\ 17mon\\ 17monipdb.datx" );
14+
15+ System .out .println (Arrays .toString (IPExt .find ("8.8.8.8" )));
16+ System .out .println (Arrays .toString (IPExt .find ("118.28.8.8" )));
17+ System .out .println (Arrays .toString (IPExt .find ("255.255.255.255" )));
18+ }
19+
20+ public static boolean enableFileWatch = false ;
21+
22+ private static int offset ;
23+ private static int [] index = new int [65536 ];
24+ private static ByteBuffer dataBuffer ;
25+ private static ByteBuffer indexBuffer ;
26+ private static Long lastModifyTime = 0L ;
27+ private static File ipFile ;
28+ private static ReentrantLock lock = new ReentrantLock ();
29+
30+ public static void load (String filename ) {
31+ ipFile = new File (filename );
32+ load ();
33+ if (enableFileWatch ) {
34+ watch ();
35+ }
36+ }
37+
38+ public static String [] find (String ip ) {
39+ String [] ips = ip .split ("\\ ." );
40+ int prefix_value = (Integer .valueOf (ips [0 ]) * 256 + Integer .valueOf (ips [1 ]));
41+ long ip2long_value = ip2long (ip );
42+ int start = index [prefix_value ];
43+ int max_comp_len = offset - 262144 - 4 ;
44+ long tmpInt ;
45+ long index_offset = -1 ;
46+ int index_length = -1 ;
47+ byte b = 0 ;
48+ for (start = start * 9 + 262144 ; start < max_comp_len ; start += 9 ) {
49+ tmpInt = int2long (indexBuffer .getInt (start ));
50+ if (tmpInt >= ip2long_value ) {
51+ index_offset = bytesToLong (b , indexBuffer .get (start + 6 ), indexBuffer .get (start + 5 ), indexBuffer .get (start + 4 ));
52+ index_length = (0xFF & indexBuffer .get (start + 7 ) << 8 ) + (0xFF & indexBuffer .get (start + 8 ));
53+ break ;
54+ }
55+ }
56+
57+ byte [] areaBytes ;
58+
59+ lock .lock ();
60+ dataBuffer .position (offset + (int ) index_offset - 262144 );
61+ areaBytes = new byte [index_length ];
62+ dataBuffer .get (areaBytes , 0 , index_length );
63+ lock .unlock ();
64+
65+ return new String (areaBytes ).split ("\t " );
66+ }
67+
68+ private static void watch () {
69+ Executors .newScheduledThreadPool (1 ).scheduleAtFixedRate (new Runnable () {
70+ @ Override
71+ public void run () {
72+ long time = ipFile .lastModified ();
73+ if (time > lastModifyTime ) {
74+ load ();
75+ }
76+ }
77+ }, 1000L , 5000L , TimeUnit .MILLISECONDS );
78+ }
79+
80+ private static void load () {
81+ lock .lock ();
82+ lastModifyTime = ipFile .lastModified ();
83+ if (dataBuffer != null && dataBuffer .position () > 0 ) {
84+ dataBuffer .clear ();
85+ indexBuffer .clear ();
86+ }
87+
88+ dataBuffer = ByteBuffer .wrap (getBytesByFile (ipFile ));
89+ dataBuffer .position (0 );
90+ offset = dataBuffer .getInt (); // indexLength
91+ byte [] indexBytes = new byte [offset ];
92+ dataBuffer .get (indexBytes , 0 , offset - 4 );
93+ indexBuffer = ByteBuffer .wrap (indexBytes );
94+ indexBuffer .order (ByteOrder .LITTLE_ENDIAN );
95+
96+ for (int i = 0 ; i < 256 ; i ++) {
97+ for (int j = 0 ; j < 256 ; j ++) {
98+ index [i * 256 + j ] = indexBuffer .getInt ();
99+ }
100+ }
101+ indexBuffer .order (ByteOrder .BIG_ENDIAN );
102+ lock .unlock ();
103+ }
104+
105+ private static byte [] getBytesByFile (File file ) {
106+ FileInputStream fin = null ;
107+ byte [] bs = new byte [new Long (file .length ()).intValue ()];
108+ try {
109+ fin = new FileInputStream (file );
110+ int readBytesLength = 0 ;
111+ int i ;
112+ while ((i = fin .available ()) > 0 ) {
113+ fin .read (bs , readBytesLength , i );
114+ readBytesLength += i ;
115+ }
116+ } catch (IOException ioe ) {
117+ ioe .printStackTrace ();
118+ } finally {
119+ try {
120+ if (fin != null ) {
121+ fin .close ();
122+ }
123+ } catch (IOException e ){
124+ e .printStackTrace ();
125+ }
126+ }
127+
128+ return bs ;
129+ }
130+
131+ private static long bytesToLong (byte a , byte b , byte c , byte d ) {
132+ return int2long ((((a & 0xff ) << 24 ) | ((b & 0xff ) << 16 ) | ((c & 0xff ) << 8 ) | (d & 0xff )));
133+ }
134+ private static int str2Ip (String ip ) {
135+ String [] ss = ip .split ("\\ ." );
136+ int a , b , c , d ;
137+ a = Integer .parseInt (ss [0 ]);
138+ b = Integer .parseInt (ss [1 ]);
139+ c = Integer .parseInt (ss [2 ]);
140+ d = Integer .parseInt (ss [3 ]);
141+ return (a << 24 ) | (b << 16 ) | (c << 8 ) | d ;
142+ }
143+
144+ private static long ip2long (String ip ) {
145+ return int2long (str2Ip (ip ));
146+ }
147+
148+ private static long int2long (int i ) {
149+ long l = i & 0x7fffffffL ;
150+ if (i < 0 ) {
151+ l |= 0x080000000L ;
152+ }
153+ return l ;
154+ }
155+ }
0 commit comments