如何存储IP地址范围与位置

时间:2013-11-13 17:19:34

标签: java algorithm data-structures

我有问题我有ip地址范围

IP                                    Location
10.1.100.200- 10.1.100.800              x
10.1.101.200- 10.1.101.800              Y
10.1.102.200- 10.1.102.800              Z etc etc

现在给出一个ip我想找到像10.1.101.270这样的位置应该给Y. 我不想要我试图使用最佳算法存储和搜索它们的代码? 如何处理这个

B+Tree?

3 个答案:

答案 0 :(得分:4)

使用,TreeMap<K, V>:您可以存储起始范围以映射该位置。 TreeMap使用红黑树数据结构对条目进行排序。包括inseritng和删除在内的关键查找操作是O(log n)。该地图提供了两个有用的功能:

higherEntry(K key):返回与key-value严重大于给定密钥相关联的key映射,如果没有此密钥则返回null

lowerEntry(K key):返回与严格小于给定键的最大键相关联的键值映射,如果没有这样的键,则返回null

使用特定IP搜索key时,您可以尝试查找此左右条目,其中包含start ip-range作为键及其对应的位置作为值。通过搜索key与这些ip-range进行比较,以确定值V(位置)。

答案 1 :(得分:4)

Interval TreeSegment Tree怎么样?如果您的“IP地址范围”是动态的,则间隔树应该更好;如果范围是静态的,那么段树应该更好,并且据说你正在执行的“刺戳查询”更好。

间隔树:

  

在计算机科学中,区间树是有序树数据   保持间隔的结构。具体来说,它允许一个人   有效地找到与任何给定间隔重叠的所有间隔或   点。它通常用于窗口查询。

查询O(log n)的时间

细分树:

  

在计算机科学中,分段树是树的数据结构   存储间隔或段。它允许查询存储的内容   段包含给定点。

查询O(log n + k)中的点,k是检索到的间隔或段的数量。

实现:

细分树implementation in Java

间隔树implementation in Java

答案 2 :(得分:1)

我会像Sage建议的那样使用TreeMap。 假设没有重叠。

public class IPSegment implements Comparable<IPSegement>{

    private long start;
    private long end;
    public IPSegement(String startIp, String endIp){
         //convert the ip address to a 32 bit integer. 

    }
    public int compareTo(IPSegement other){

         return this.start - other.start;  //assume no overlap
    }

    public int equals(IPSegement other){
      // check both start and end
    }

    public boolean contains(long ip){
      //check whether 'ip' is in this range
    }
}


public class IPSegmentMap{
     private TreeMap<IPSegement> map = new TreeMap<IPSegement>();
     public void add(String start, String end, String location){
          //...
     }

     public String find(String ipAddress){
         long ip = convertIPtoInt(ipAddress);
         IPSegement request = new IPSegement(ip,ip);
         IPSegement exist = map.floorKey(request);
         if(exist.contains(ip)){
             return map.get(exist);
         }

     }

}