private int CountNewerEntries( TimeSpan age )
{
if ( age < TimeSpan.Zero ) {
throw new ArgumentOutOfRangeException( "age", "Age must be non-negative." );
}
int minTimestamp = ( int )DateTime.UtcNow.Subtract( age ).ToUnixTime();
if ( isPreloaded ) {
fixed ( BlockDBEntry* ptr = cacheStore ) {
for ( int i = 0; i < CacheSize; i++ ) {
if ( ptr[i].Timestamp < minTimestamp ) {
return CacheSize - i;
}
}
}
} else {
Flush( false );
if ( !File.Exists( FileName ) )
return -1;
using ( FileStream fs = OpenRead() ) {
long length = fs.Length;
long bytesReadTotal = 0;
int bufferSize = ( int )Math.Min( SearchBufferSize, length );
byte[] buffer = new byte[bufferSize];
while ( bytesReadTotal < length ) {
long offset = Math.Max( 0, length - bytesReadTotal - SearchBufferSize );
fs.Seek( offset, SeekOrigin.Begin );
int bytesToRead = ( int )Math.Min( length - bytesReadTotal, SearchBufferSize );
int bytesLeft = bytesToRead;
int bytesRead = 0;
while ( bytesLeft > 0 ) {
int readPass = fs.Read( buffer, bytesRead, bytesLeft );
if ( readPass == 0 )
throw new EndOfStreamException();
bytesRead += readPass;
bytesLeft -= readPass;
}
bytesReadTotal += bytesRead;
fixed ( byte* parr = buffer ) {
BlockDBEntry* entries = ( BlockDBEntry* )parr;
int entryCount = bytesRead / sizeof( BlockDBEntry );
if ( bytesRead % sizeof( BlockDBEntry ) != 0 )
throw new DataMisalignedException();
for ( int i = entryCount - 1; i >= 0; i-- ) {
if ( entries[i].Timestamp < minTimestamp ) {
return entryCount - i;
}
}
}
}
}
}
return -1;
}