假设我想为2001:0DB8 :: / 32范围内的人分配IPv6地址。大多数是按顺序发出的,但有些是非顺序的。此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地址,我仍然需要按顺序计算从该地址到下一个地址的步数,然后在新地址之前返回到壁橱分配的地址。并纠正其“下一个地址的步骤”。似乎仍然是一个缓慢的过程。
有更好的方法吗?
答案 0 :(得分: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