mirror of
https://github.com/MariaDB/server.git
synced 2025-01-22 23:04:20 +01:00
4860352fb8
d stands for disk-byte-order (as opposed to n for network-byte-order) Disk-byte-order set as Intel byte order for now git-svn-id: file:///svn/toku/tokudb@10694 c7de825b-a66e-492c-adef-691d508d4ae1
76 lines
2.6 KiB
C
76 lines
2.6 KiB
C
/* Buffered read. */
|
|
|
|
#include "includes.h"
|
|
|
|
struct bread {
|
|
int64_t fileoff; // The byte before this offset is the next byte we will read (since we are reading backward)
|
|
int fd;
|
|
int bufoff; // The current offset in the buf. The next byte we will read is buf[bufoff-1] (assuming that bufoff>0).
|
|
char *buf; // A buffer with at least bufoff bytes in it.
|
|
};
|
|
|
|
BREAD create_bread_from_fd_initialize_at(int fd) {
|
|
BREAD XMALLOC(result);
|
|
int r = toku_os_get_file_size(fd, &result->fileoff);
|
|
assert(r==0);
|
|
result->fd=fd;
|
|
result->bufoff=0;
|
|
result->buf = 0;
|
|
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;
|
|
const int i4 = sizeof(u_int32_t);
|
|
while (nbytes > 0) {
|
|
// read whatever we can out of the buffer.
|
|
if (br->bufoff>0) {
|
|
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;
|
|
result += to_copy;
|
|
br->bufoff -= to_copy;
|
|
}
|
|
if (nbytes>0) {
|
|
assert(br->bufoff==0);
|
|
u_int32_t compressed_length_n, uncompressed_length_n;
|
|
assert(br->fileoff>=i4); // there better be the three lengths plus the compressed data.
|
|
{ ssize_t r = pread(br->fd, &compressed_length_n, i4, br->fileoff- i4); assert(r==i4); }
|
|
u_int32_t compressed_length = toku_dtoh32(compressed_length_n);
|
|
assert(br->fileoff >= compressed_length + 3*i4);
|
|
{ ssize_t r = pread(br->fd, &uncompressed_length_n, i4, br->fileoff-2*i4); assert(r==i4); }
|
|
u_int32_t uncompressed_length = toku_dtoh32(uncompressed_length_n);
|
|
char *XMALLOC_N(compressed_length, zbuf);
|
|
{
|
|
ssize_t r = pread(br->fd, zbuf, compressed_length, br->fileoff- compressed_length -2*i4);
|
|
assert(r==(ssize_t)compressed_length);
|
|
}
|
|
{
|
|
u_int32_t compressed_length_n_again;
|
|
ssize_t r = pread(br->fd, &compressed_length_n_again, i4, br->fileoff-compressed_length-3*i4); assert(r==i4);
|
|
assert(compressed_length_n_again == compressed_length_n);
|
|
}
|
|
uLongf destlen = uncompressed_length;
|
|
XREALLOC_N(uncompressed_length, br->buf);
|
|
uncompress((Bytef*)br->buf, &destlen, (Bytef*)zbuf, compressed_length);
|
|
assert(destlen==uncompressed_length);
|
|
toku_free(zbuf);
|
|
|
|
br->bufoff = uncompressed_length;
|
|
br->fileoff -= (compressed_length + 3*i4);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int bread_has_more(BREAD br) {
|
|
return (br->fileoff>0) || (br->bufoff>0);
|
|
}
|