#! perl -slw use strict; local $, = ' '; my( $A, $C, @B ) = ( undef, 0 ); open SPARSE, '+> :raw', \$A; sub readA{ seek SPARSE, 4 * $_[ 0 ], 0; sysread SPARSE, my $n, 4; unpack 'N', $n; } sub writeA{ seek SPARSE, 4 * $_[ 0 ], 0; syswrite SPARSE, pack( 'N', $_[ 1 ] ), 4; } sub query{ my $i = shift; my $a = readA( $i ) || -1; return 0 unless 0 <= $a and $a < $C; my $b = $B[ $a ]; return $b == $i ? 1 : 0; } sub insert{ my $i = shift; if( !query( $i ) ) { $B[ $C ] = $i; writeA( $i, $C ); $C++ } } sub del{ my $i = shift; if( query( $i ) ) { my $a = readA( $i ); my $b = $B[ --$C ]; $B[ $a ] = $b; writeA( $b, $a ); } } sub clear{ $C = 0; } my @numbers = map{ int rand( 2**16 ) } 1 .. 10; print 'Query before insert'; printf "%5d : %s\n", $_, query( $_ ) for @numbers; insert $_ for @numbers; print "\nQuery after insert"; printf "%5d : %s\n", $_, query( $_ ) for @numbers; del $_ for @numbers[ 0..4 ]; ## Delete half print "\nQuery after deleting half"; printf "%5d : %s\n", $_, query( $_ ) for @numbers; del $_ for @numbers; ## Delete them all regardless if they still exists print "\nQuery after deleting the rest"; printf "%5d : %s\n", $_, query( $_ ) for @numbers;