mariadb/newbrt/bread.c
Bradley C. Kuszmaul 75369283fa Merge changes back to tokudb.1032b. Fixes #1305.
git-svn-id: file:///svn/toku/tokudb.1032b@8272 c7de825b-a66e-492c-adef-691d508d4ae1
2013-04-16 23:57:30 -04:00

58 lines
1.7 KiB
C

/* Buffered read. */
#include "includes.h"
struct bread {
toku_off_t current_offset; // The current offset to be read (in the file). That offset includes anything that is unread in the buffer.
int fd;
size_t bufsize;
char *buf; // A buffer of size bufsize;
int bufoff; // The current offset buf.
};
BREAD create_bread_from_fd_initialize_at(int fd, toku_off_t filesize, size_t bufsize) {
BREAD MALLOC(result);
result->current_offset=filesize;
result->fd=fd;
result->bufoff=0;
result->bufsize=bufsize;
MALLOC_N(bufsize, result->buf);
return result;
}
int close_bread_without_closing_fd(BREAD br) {
toku_free(br->buf);
toku_free(br);
return 0;
}
ssize_t bread_backwards(BREAD br, void *vbuf, size_t nbytes) {
char *buf=vbuf;
ssize_t result=0;
while (nbytes > 0) {
assert(br->current_offset >= (toku_off_t)nbytes);
// read whatever we can out of the buffer.
{
size_t to_copy = ((size_t)br->bufoff >= nbytes) ? nbytes : (size_t)br->bufoff;
memcpy(buf+nbytes-to_copy, &br->buf[br->bufoff-to_copy], to_copy);
nbytes -= to_copy;
br->current_offset -= to_copy;
result += to_copy;
br->bufoff -= to_copy;
}
if (nbytes>0) {
assert(br->bufoff==0);
size_t to_read = ((u_int64_t)br->current_offset >= (u_int64_t)br->bufsize) ? br->bufsize : (size_t)br->current_offset;
assert(to_read>0 && to_read<=br->bufsize);
ssize_t r = pread(br->fd, br->buf, to_read, br->current_offset-to_read);
assert(r==(ssize_t)to_read);
br->bufoff = to_read;
}
}
return result;
}
int bread_has_more(BREAD br) {
return br->current_offset>0;
}