def range_usage(ip_start, ip_end, ip_type, get_objects=False):

    istart, iend, ipf_q = start_end_filter(ip_start, ip_end, ip_type)

    def get_ip(rec):
        return two_to_one(rec.ip_upper, rec.ip_lower)

    # This should be done in the db
    lists = [sorted(AddressRecord.objects.filter(ipf_q), key=get_ip),
             sorted(PTR.objects.filter(ipf_q), key=get_ip),
             sorted(StaticInterface.objects.filter(ipf_q), key=get_ip)]
    # This should be done in the db
    free_ranges = []

    def cmp_ip_upper_lower(a, b):
        if a.ip_upper > b.ip_upper:
            return a
        elif a.ip_upper < b.ip_upper:
            return b
        elif a.ip_lower > b.ip_lower:
            return a
        elif a.ip_lower < b.ip_lower:
            return b
        else:
            return a

    unused = 0
    minimum_i = 0
    rel_start = int(istart)
    end = int(iend)
    while True:
        if rel_start > end:
            break
        lists = [l for l in lists if l]
        if not lists:
            free_ranges.append((rel_start, end))
            unused += end - rel_start + 1
            break

        min_list = min(lists, key=lambda x: two_to_one(x[0].ip_upper,
                                                       x[0].ip_lower))

        minimum = min_list[0]
        minimum_i = two_to_one(minimum.ip_upper, minimum.ip_lower)
        unused += minimum_i - rel_start
        if minimum_i != rel_start:
            free_ranges.append((rel_start, minimum_i - 1))

        if get_objects:
            objects = ['objects']
        for l in lists:
            while (l and
                    l[0].ip_upper == minimum.ip_upper and
                    l[0].ip_lower == minimum.ip_lower):
                if get_objects:
                    objects.append(l.pop(0))
                else:
                    l.pop(0)
        if get_objects:
            free_ranges.append(objects)

        rel_start = minimum_i + 1

    range_usage = {
        'unused': unused,
        'used': int(iend) - int(istart) - unused + 1,
        'free_ranges': free_ranges,
    }

    return range_usage
:param ip_start: Start ip
dataset/ETHPy150Open rtucker-mozilla/mozilla_inventory/core/range/utils.py/range_usage