1

假设我想将 IPv6 地址分配给 2001:0DB8::/32 范围内的人。大多数是按顺序发出的,但有些是非连续的。该 DB 表显示已分配的地址。

+-----------------------------------------+
|                 Address                 |
+-----------------------------------------+
| 2001:0DB8:0000:0000:0000:0000:0000:0001 |
| 2001:0DB8:0000:0000:0000:0000:0000:0002 |
| 2001:0DB8:0000:0000:0000:0000:0000:0003 |
| 2001:0DB8:0000:0000:0000:0000:0000:0009 |
| 2001:0DB8:0000:0000:0000:0000:0F00:0001 |
| 2001:0DB8:0000:0000:0000:0000:0F00:0002 |
+-----------------------------------------+

请注意,它是稀疏填充的 - 前 3 个被占用,然后有 5 个可用地址,直到下一个被占用,然后在另一个地址被占用之前有几百万个地址的间隙。

我想做的是为用户分配下一个可用地址,从子网的开头开始。在这种情况下,从一开始就很容易,发现还没有 2001:0DB8::4 的记录,然后使用那个记录。但最终下一个可用地址可能距离子网起点有数千或数百万步。一次遍历一个地址的数据库将是一个坏主意。

我想在表中添加另一个字段,以便每个地址指示其自身与列表中的下一个地址之间有多少可用地址:

+-----------------------------------------+--------------------+
|                 Address                 | Steps to next addr |
+-----------------------------------------+--------------------+
| 2001:0DB8:0000:0000:0000:0000:0000:0001 |                  1 |
| 2001:0DB8:0000:0000:0000:0000:0000:0002 |                  1 |
| 2001:0DB8:0000:0000:0000:0000:0000:0003 |                  6 |
| 2001:0DB8:0000:0000:0000:0000:0000:0009 |           15728632 |
| 2001:0DB8:0000:0000:0000:0000:0F00:0001 |                  2 |
| 2001:0DB8:0000:0000:0000:0000:0F00:0003 |                    |
+-----------------------------------------+--------------------+

但我不确定这对我有帮助。如果 IP 地址分配在稀疏部分中间的某个位置,我仍然需要计算从该地址到下一个地址的顺序有多少步,然后返回新地址之前的壁橱分配地址并更正其“下一个地址的步骤”。似乎仍然是一个缓慢的过程。

有一个更好的方法吗?

4

1 回答 1

1

只需在此处稍微调整您的方法即可解决此问题。我假设您想在这里填补未使用的空白的原因是因为您有一个现有的人口稀少的数据库,您想更好地利用它。

保留您的原始表格,但单独存储一个next_address字段(例如,在Settings表格中)。首次部署代码时,next_address将在2001:db8::1.

您的get_next_address()函数将如下所示:

def initialise_settings():
    if not Settings.exists('next_address'):
         Settings.set('next_address', IPv6('2001:db8::1'))

def get_next_address():

    next = Settings.get('next_address')

    # Check for already filled rows -- breaks loop upon finding gap
    while Database.row_exists({'Address': next}):
        next += 1

    Settings.set('next_address', next + 1)
    return next

get_next_address() # 2001:db8::4
get_next_address() # 2001:db8::5
get_next_address() # 2001:db8::6
# ...
get_next_address() # 2001:db8::f00:0
get_next_address() # 2001:db8::f00:2
get_next_address() # 2001:db8::f00:4
get_next_address() # 2001:db8::f00:5
于 2013-06-22T01:59:26.753 回答