ValueInterval:
PROC [table: Table, value:
REF]
RETURNS [interval: Interval] = {
sizeOfValues: REF INT ← NARROW [table.userData];
pos: REF INT ← NARROW [value];
interval ← [pos^-sizeOfValues^, pos^+sizeOfValues^];
};
Test:
PROC [numberOfValues:
NAT, rangeMax:
NAT]
RETURNS [table: Table, results:
REF Results, intervs:
LIST
OF Interval ←
NIL] = {
sizeOfValues: NAT ← 2;
rs: Random.RandomStream ← Random.Create[rangeMax, rangeMax];
last: REF;
pos: INT;
count: INT ← 0;
Count: PROC [table: Table, v: Value] RETURNS [BOOL ← FALSE] = {count ← count+1};
Each: PROC [table: Table, value: Value] RETURNS [BOOL ← FALSE] = {intervs ← CONS [ValueInterval[table, value], intervs]};
MakeError: PROC [table: Table, v: Value] RETURNS [BOOL ← FALSE] = {ERROR};
table ← Create[range: [-sizeOfValues, rangeMax+sizeOfValues], valueInterval: ValueInterval, userData: NEW [INT ← sizeOfValues]];
THROUGH [0 .. numberOfValues]
DO
pos ← Random.NextInt[rs];
Insert[table, (last ← NEW [INT ← pos])];
ENDLOOP;
IF table.size#numberOfValues+1 THEN ERROR;
Delete[table, last];
IF table.size#numberOfValues THEN ERROR;
Delete[table, last];
IF table.size#numberOfValues THEN ERROR;
results ← NEW [Results[table.data.hashSize]];
FOR i:
NAT
IN [0 .. table.data.hashSize)
DO
FOR list:
LIST
OF Value ← table.data[i], list.rest
WHILE list#
NIL
DO
results[i] ← results[i]+1;
ENDLOOP;
ENDLOOP;
[] ← Enumerate[table, Count];
IF count#numberOfValues THEN ERROR;
[] ← Enumerate[table, Each, [rangeMax/2-10*sizeOfValues, rangeMax/2+10*sizeOfValues]];
[] ← Enumerate[table, MakeError, [-sizeOfValues-10, -sizeOfValues-5]];
};