in component/libfuse/native_file_io.h [162:231]
static int read_ahead_handler(char *path, char *buf, size_t size, off_t offset, file_handle_t* handle_obj)
{
int new_read = 0;
/* Random read determination logic :
handle_obj->random_reads : is counter used for this
- For every sequential read decrement this counter by 1
- For every new read from physical file (random read or buffer refresh) increment the counter by 2
- At any point if the counter value is > 5 then caller will disable read-ahead on this handle
: If file is being read sequentially then counter will be negative and a buffer refresh will not skew the counter much
: If file is read sequentially and later application moves to random read, at some point we will disable read-ahead logic
: If file is read randomly then counter will be positive and we will disable read-ahead after 2-3 reads
: If file is read randomly first and then sequentially then we assume it will be random read and disable the read-ahead
*/
if ((handle_obj->buff_start == 0 && handle_obj->buff_end == 0) ||
offset < handle_obj->buff_start ||
offset >= handle_obj->buff_end)
{
// Either this is first read call or read is outside the current buffer boundary
// So we need to read a fresh buffer from physical file
new_read = 1;
handle_obj->random_reads += 2;
} else {
handle_obj->random_reads--;
}
if (new_read) {
// We need to refresh the data from file
int read = native_pread(path, handle_obj->buff, RA_BLOCK_SIZE, offset, handle_obj);
FILE *fp = fopen("blobfuse2_nat.log", "a");
if (fp) {
fprintf(fp, "File %s, Offset %ld, size %ld, new read %d\n",
path, offset, size, read);
fclose(fp);
}
if (read <= 0) {
// Error or EOF reached to just return 0 now
return read;
}
handle_obj->buff_start = offset;
handle_obj->buff_end = offset + read;
}
// Buffer is populated so calculate how much to copy from here now.
int start = offset - handle_obj->buff_start;
int left = (handle_obj->buff_end - offset);
int copy = (size > left) ? left : size;
FILE *fp = fopen("blobfuse2_nat.log", "a");
if (fp) {
fprintf(fp, "File %s, Offset %ld, size %ld, buff start %ld, buff end %ld, start %d, left %d, copy %d\n",
path, offset, size, handle_obj->buff_start, handle_obj->buff_end, start, left, copy);
fclose(fp);
}
memcpy(buf, (handle_obj->buff + start), copy);
if (copy < size) {
// Less then request data was copied so read from next offset again
// We need to handle this here because if we return less then size fuse is not asking from
// correct offset in next read, it just goes to offset + size only.
copy += read_ahead_handler(path, (buf + copy), (size - copy), (offset + copy), handle_obj);
}
return copy;
}