# Optimizing an IP generation method

I have designed a proxy server which has the feature to manage miniature separate networks. Each network has space to have up to 500 nodes or 500 IPs. The code for getting a new virtual IP is based on a bit flag based approach. I have used an array of DWORD (Blocks) so as to skip entire 32 IP chunks, if the block is fully set. I have also divided the DWORD further into byte based checking. so as to forgo checking of all 32 bits as much as possible. The code also skips any addresses with the lower octet being 0 or 1. The code only gets the lower two octets while the higher two octets are fixed to 10.0.

I know the problem with this approach is that the higher the IP, the slower it gets found. So how can I diminish the slow down? Should I go higher towards LongWORD for one block? Should I check the Block byte by byte or in smaller/bigger chunks? Or just abandon this and find some other algorithm?

The limit to be 500 is more of a marketing move than a technical one. We currently have to manage 1800 such networks. These networks are academic in nature and have very anomalous behavior patterns, as such that we are seeing almost 10000 requests per second in peak times.

---

var
fIPPool : array [0..15] of DWORD;

---

constructor xxxx;
begin

fIPPool [0]  := $00000003; // Skips 0.0 and 0.1 fIPPool [7] :=$80000000; // Skips 0.255
fIPPool [8]  := $00000003; // Skips 1.0 and 1.1 fIPPool [15] :=$FE000000; // Skips 1.249-1.255

end;

---

function GetIP: DWORD;
var
Block, Cell : Byte;

function GetCell ( const ABlock: DWORD; var AMask: DWORD; const ACell : Byte )
: Byte; inline;
begin
Result := ACell;
while ( ABlock and AMask ) <> 0 do
begin
Result := Result + 1;
end;
end;

begin

Result := 0;
for Block := 0 to 15 do
begin

if fIPPool [Block] <> $FFFFFFFF then begin if ( fIPPool [Block] and$000000FF ) < $000000FF then begin Mask :=$00000001;
Cell := GetCell ( fIPPool [Block], Mask, 0 )
end
else if ( fIPPool [Block] and $0000FFFF ) <$0000FFFF then
begin
Mask := $00000100; Cell := GetCell ( fIPPool [Block], Mask, 8 ) end else if ( fIPPool [Block] and$00FFFFFF ) < $00FFFFFF then begin Mask :=$00010000;
Cell := GetCell ( fIPPool [Block], Mask, 16 );
end
else
begin
Mask := $01000000; Cell := GetCell ( fIPPool [Block], Mask, 24 ); end; Result := ( Block * 32 ) + Cell; fIPPool [Block] := fIPPool [Block] or Mask; break; end; end; end; // one can use the following line to get the IPs if run in a for-loop for 500 times Memo1.Lines.Add ( IntToStr ( ( IP and$FF00 ) shr 8 ) +'.'+ IntToStr ( IP and \$00FF ));

• Can you add some detail about why you have 500 and not 512 addresses in each block? Commented Nov 29, 2013 at 16:40
• Also, how many of these networks do you have? Commented Nov 29, 2013 at 16:45

Block-Slice  32-bit 64-bit