mariadb/newbrt/bread.c
Bradley C. Kuszmaul 1f796663cd Check in the code for compressing the rolltmp file.
This was a tricky merge.  In the 1332a directory I did:
{{{
svn merge https://svn.tokutek.com/tokudb/toku/tokudb.1032b+1332@8415 https://svn.tokutek.com/tokudb/toku/tokudb.1032b+1332@8416
}}}
Then I was able to resolve the conflicts.

Then in the main line I did:
{{{
svn merge -r9042:9046 https://svn.tokutek.com/tokudb/toku/tokudb.1332a
}}}

Fixes #1332.


git-svn-id: file:///svn/toku/tokudb@9047 c7de825b-a66e-492c-adef-691d508d4ae1
2013-04-16 23:57:38 -04:00

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 = ntohl(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 = ntohl(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);
}