IP库查询算法

最近项目中需要实现一个IP库查询的模块,自己实现了一个算法,借鉴了一致性哈希算法的原理。

IP库的数据结构如下:

start_ip_num(long)             start_ip(String) end_ip_num(long)         end_ip     city city_id city_cd ip_route_status update_date province

起始IP转成long型数据         起始IP                结束IP转成long型数据    结束IP     城市                                                                               省份

思路是:

1.      从数据库初始化IP地址库到内存,起始IP封装成IPData对象,包含起始IP和省市信息等;

2.      开始IP封装成long型数据作为key,IPData对象作为value,对应成key-value的Map型数据结构

3.      对key作升序排序,和IPData插入TreeMap结构集合

4.      将目标IP转化成long型数据,找出TreeMap中找出小于等于目标IP的key集合

5.      获取这个集合的最后一个key,即逆时针距离目标IP最近的一条,即目标IP所在的IP区间key

6.      根据获取到的最后一个key从Map中找到对应的IPData对象,获取省市信息

注:TreeMap的查询时间复杂度为o(logn)


package com.suning.ipRoute;

/**
 * Created by 15061760 on 2016/3/2 0002.
 */
public class IPData {
    private long startIPNum;
    private long endIPNum;
    private String startIp;
    private String endIp;
    private String city;
    private String province;

    public long getStartIPNum() {
        return startIPNum;
    }

    public void setStartIPNum(long startIPNum) {
        this.startIPNum = startIPNum;
    }

    public long getEndIPNum() {
        return endIPNum;
    }

    public void setEndIPNum(long endIPNum) {
        this.endIPNum = endIPNum;
    }

    public String getStartIp() {
        return startIp;
    }

    public void setStartIp(String startIp) {
        this.startIp = startIp;
    }

    public String getEndIp() {
        return endIp;
    }

    public void setEndIp(String endIp) {
        this.endIp = endIp;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    @Override
    public String toString() {
        return ("<<" + this.getStartIp() + ";" + this.getEndIp() + ";" + this.getCity() + ";" + this.getProvince() + ">>");
    }
}


package com.suning.ipRoute;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.*;

/**
 * Created by 15061760 on 2016/3/2 0002.
 */
public class IPSearch {

    private static final String filePath = "F:\\ip_route.xml";
    static final String START_IP_NUM = "start_ip_num";
    static final String END_IP_NUM = "end_ip_num";
    static final String START_IP = "start_ip";
    static final String END_IP = "end_ip";
    static final String CITY = "city";
    static final String PROVINCE = "province";
    static final String ip = "58.101.255.192";
    static final long ip_long = 58101255192L;


    public static void main(String[] args) throws Exception {
        //读文件
        SAXReader saxReader = new SAXReader();
        Document doc = saxReader.read(filePath);
        Element root = doc.getRootElement();
        Iterator<Element> it = root.elementIterator();
        SortedMap<Long, IPData> sortedMap = new TreeMap<Long, IPData>();
        while (it.hasNext()) {
            Element item = it.next();
            IPData ipData = new IPData();
            ipData.setStartIPNum(Long.parseLong(item.elementText(START_IP_NUM)));
            ipData.setEndIPNum(Long.parseLong(item.elementText(END_IP_NUM)));
            ipData.setStartIp(item.elementText(START_IP));
            ipData.setEndIp(item.elementText(END_IP));
            ipData.setCity(item.elementText(CITY));
            ipData.setProvince(item.elementText(PROVINCE));
            sortedMap.put(ipData.getStartIPNum(), ipData);
        }

        List<Long> ipList = new ArrayList<Long>();
        Random random = new Random();
        //随机生成30000条数据
        for (int i = 0; i < 10; i++) {
            int[] ip = new int[4];
            ip[0] = random.nextInt(255);
            ip[1] = random.nextInt(255);
            ip[2] = random.nextInt(255);
            ip[3] = random.nextInt(255);
            long targetIP = getIP(ip);
            ipList.add(targetIP);
        }
        System.out.println("=========================");
        long start = System.currentTimeMillis();
        for (int i = 0; i < ipList.size(); i++) {
            long targetIP = ipList.get(i);
            SortedMap<Long, IPData> subMap = sortedMap.headMap(targetIP);
            if (subMap != null && subMap.size() > 0) {
                long key = subMap.lastKey();
                IPData ipData = subMap.get(key);
//                System.out.println("目标IP:" + targetIP + ":[" + ipData.getProvince() + ";" + ipData.getCity() + "]");
            }
        }
        System.out.println(System.currentTimeMillis() - start);
//        SortedMap<Long, IPData> subMap = sortedMap.headMap(ip_long);
//        long key = subMap.lastKey();
//        IPData ipData = sortedMap.get(key);
//        long end = System.currentTimeMillis();
//        System.out.println(end - start);
//        System.out.println(ipData.getProvince() + "----" + ipData.getCity());
    }

    private static long getIP(int[] ip_array) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            if (i == 0) {
                sb.append(ip_array[i]);
            } else {
                if (String.valueOf(ip_array[i]).length() == 1) {
                    sb.append("00").append(ip_array[i]);
                } else if (String.valueOf(ip_array[i]).length() == 2) {
                    sb.append("0").append(ip_array[i]);
                } else {
                    sb.append(ip_array[i]);
                }
            }
        }
        return Long.parseLong(sb.toString());
    }

}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值