Store Ip4Path as int instead of List[int]
This commit is contained in:
parent
4d966371b2
commit
d976752797
49
database.py
49
database.py
|
@ -20,7 +20,7 @@ PathType = enum.Enum('PathType', 'Rule Hostname Zone Asn Ip4 Ip6')
|
||||||
RulePath = typing.Union[None]
|
RulePath = typing.Union[None]
|
||||||
Asn = int
|
Asn = int
|
||||||
DomainPath = typing.List[str]
|
DomainPath = typing.List[str]
|
||||||
Ip4Path = typing.List[int]
|
Ip4Path = typing.Tuple[int, int] # value, prefixlen
|
||||||
Ip6Path = typing.List[int]
|
Ip6Path = typing.List[int]
|
||||||
Path = typing.Union[RulePath, DomainPath, Asn, Ip4Path, Ip6Path]
|
Path = typing.Union[RulePath, DomainPath, Asn, Ip4Path, Ip6Path]
|
||||||
TypedPath = typing.Tuple[PathType, Path]
|
TypedPath = typing.Tuple[PathType, Path]
|
||||||
|
@ -139,33 +139,33 @@ class Database(Profiler):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def pack_ip4address(address: str) -> Ip4Path:
|
def pack_ip4address(address: str) -> Ip4Path:
|
||||||
addr: Ip4Path = [0] * 32
|
addr = 0
|
||||||
octets = [int(octet) for octet in address.split('.')]
|
for split in address.split('.'):
|
||||||
for b in range(32):
|
addr = addr << 4 + int(split)
|
||||||
if (octets[b//8] >> b % 8) & 0b1:
|
return (addr, 32)
|
||||||
addr[b] = 1
|
|
||||||
return addr
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unpack_ip4address(address: Ip4Path) -> str:
|
def unpack_ip4address(address: Ip4Path) -> str:
|
||||||
|
addr, prefixlen = address
|
||||||
|
assert prefixlen == 32
|
||||||
|
octets: typing.List[int] = list()
|
||||||
octets = [0] * 4
|
octets = [0] * 4
|
||||||
for b, bit in enumerate(address):
|
for o in reversed(range(4)):
|
||||||
octets[b//8] = (octets[b//8] << 1) + bit
|
octets[o] = addr & 0xFF
|
||||||
|
addr >>= 8
|
||||||
return '.'.join(map(str, octets))
|
return '.'.join(map(str, octets))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def pack_ip4network(network: str) -> Ip4Path:
|
def pack_ip4network(network: str) -> Ip4Path:
|
||||||
address, prefixlen_str = network.split('/')
|
address, prefixlen_str = network.split('/')
|
||||||
prefixlen = int(prefixlen_str)
|
prefixlen = int(prefixlen_str)
|
||||||
return Database.pack_ip4address(address)[:prefixlen]
|
addr, _ = Database.pack_ip4address(address)
|
||||||
|
return (addr, prefixlen)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unpack_ip4network(network: Ip4Path) -> str:
|
def unpack_ip4network(network: Ip4Path) -> str:
|
||||||
address = network.copy()
|
address, prefixlen = network
|
||||||
prefixlen = len(network)
|
addr = Database.unpack_ip4address((address, 32))
|
||||||
for _ in range(32-prefixlen):
|
|
||||||
address.append(0)
|
|
||||||
addr = Database.unpack_ip4address(address)
|
|
||||||
return f'{addr}/{prefixlen}'
|
return f'{addr}/{prefixlen}'
|
||||||
|
|
||||||
def update_references(self) -> None:
|
def update_references(self) -> None:
|
||||||
|
@ -224,20 +224,19 @@ class Database(Profiler):
|
||||||
|
|
||||||
def get_ip4(self, ip4_str: str) -> typing.Iterable[TypedPath]:
|
def get_ip4(self, ip4_str: str) -> typing.Iterable[TypedPath]:
|
||||||
self.enter_step('get_ip4_pack')
|
self.enter_step('get_ip4_pack')
|
||||||
ip4 = self.pack_ip4address(ip4_str)
|
ip4, prefixlen = self.pack_ip4address(ip4_str)
|
||||||
self.enter_step('get_ip4_brws')
|
self.enter_step('get_ip4_brws')
|
||||||
dic = self.ip4tree
|
dic = self.ip4tree
|
||||||
depth = 0
|
for i in reversed(range(prefixlen)):
|
||||||
for part in ip4:
|
part = (ip4 >> i) & 0b1
|
||||||
if dic.match:
|
if dic.match:
|
||||||
self.enter_step('get_ip4_yield')
|
self.enter_step('get_ip4_yield')
|
||||||
yield (PathType.Ip4, ip4[:depth])
|
yield (PathType.Ip4, (ip4, 32-i))
|
||||||
self.enter_step('get_ip4_brws')
|
self.enter_step('get_ip4_brws')
|
||||||
next_dic = dic.children[part]
|
next_dic = dic.children[part]
|
||||||
if next_dic is None:
|
if next_dic is None:
|
||||||
return
|
return
|
||||||
dic = next_dic
|
dic = next_dic
|
||||||
depth += 1
|
|
||||||
if dic.match:
|
if dic.match:
|
||||||
self.enter_step('get_ip4_yield')
|
self.enter_step('get_ip4_yield')
|
||||||
yield (PathType.Ip4, ip4)
|
yield (PathType.Ip4, ip4)
|
||||||
|
@ -307,10 +306,11 @@ class Database(Profiler):
|
||||||
self.enter_step('set_ip4add_pack')
|
self.enter_step('set_ip4add_pack')
|
||||||
if is_first_party or source:
|
if is_first_party or source:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
ip4, prefixlen = self.pack_ip4address(ip4address_str)
|
||||||
self.enter_step('set_ip4add_brws')
|
self.enter_step('set_ip4add_brws')
|
||||||
ip4address = self.pack_ip4address(ip4address_str)
|
|
||||||
dic = self.ip4tree
|
dic = self.ip4tree
|
||||||
for part in ip4address:
|
for i in reversed(range(prefixlen)):
|
||||||
|
part = (ip4 >> i) & 0b1
|
||||||
if dic.match:
|
if dic.match:
|
||||||
# Refuse to add ip4address whose network is already matching
|
# Refuse to add ip4address whose network is already matching
|
||||||
return
|
return
|
||||||
|
@ -330,9 +330,10 @@ class Database(Profiler):
|
||||||
if is_first_party or source:
|
if is_first_party or source:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
self.enter_step('set_ip4net_brws')
|
self.enter_step('set_ip4net_brws')
|
||||||
ip4network = self.pack_ip4network(ip4network_str)
|
ip4, prefixlen = self.pack_ip4network(ip4network_str)
|
||||||
dic = self.ip4tree
|
dic = self.ip4tree
|
||||||
for part in ip4network:
|
for i in reversed(range(prefixlen)):
|
||||||
|
part = (ip4 >> i) & 0b1
|
||||||
if dic.match:
|
if dic.match:
|
||||||
# Refuse to add ip4network whose parent network
|
# Refuse to add ip4network whose parent network
|
||||||
# is already matching
|
# is already matching
|
||||||
|
|
Loading…
Reference in a new issue