It depends if you think that the IP ranges may overlap or not. If not, the solution is pretty simple:
- use a hash collection to store provider data.
- use zset to index the maximum value of your ranges.
- get a (unique) range whose maximum value is greater than IP
- check the min value of this range below IP
Example:
Here are my providers. Each of them is identified with an identifier. Please note that I can add additional properties for each provider:
> hmset providers:1 name P1 min 3232235786 max 3232235826 OK > hmset providers:2 name P3 min 1232235786 max 1232235826 OK > hmset providers:3 name P3 min 2232235786 max 2232235826 OK > hmset providers:4 name P4 min 4232235786 max 4232235826 OK
Each time a provider is added to the system, it is necessary to maintain the index (manually: this is Redis, not a relational database). Score is the maximum value, member is the range identifier.
> zadd providers:index 3232235826 1 1232235826 2 2232235826 3 4232235826 4 (integer) 4 > zrange providers:index 0 -1 1) "2" 2) "3" 3) "1" 4) "4"
Now, to request a unique range corresponding to the IP address, you will need 2 roundtrips:
> zrangebyscore providers:index 3232235787 +inf LIMIT 0 1 1) "1" > hgetall providers:1 1) "name" 2) "P1" 3) "min" 4) "3232235786" 5) "max" 6) "3232235826"
Then the client program simply needs to verify that your IP is greater than or equal to the minimum address of the returned range.
Now, if you think that ranges can overlap, the solution is much more complicated, and this has already been explained here .
Didier spezia
source share