Re: [librsync-devel] Re: [rfc] hide rs_buffers_t from public interface
Martin Pool <[email protected]> Tue, 17 Feb 2004 10:41:11 +1100
| Newsgroups | gmane.network.librsync.general |
|---|---|
| Message-ID | <[email protected]> |
On 16 Feb 2004, David Helgason <[email protected]> wrote: > On 16. feb 2004, at 05:36, Martin Pool wrote: > > >I was thinking on the weekend about what could be done to make the > >librsync interface a bit simpler. > > > >It might be better to have the library do all input and output through > >user callbacks, rather than exposing its buffering at all. This is to > >say that something like rs_job_drive would be the main interface, and > >rs_buffers_t would be removed, or at least not public. When the > >library needs some input data, it calls the input callback. Similarly > >for output and for reading blocks from the basis file. > > I don't mind this interface at all, but I need the buffer interface to > do my work (run the algorithms on data inside postgresql) as I've got > no file descriptors in there. So please don't remove or hide it. > > I also avoided the callback stuff as there wouldn't have been any win > there (and a net loss in more complex code and having the code spread > out: something I dislike when doing C). The buffer interface may take a > few minutes to wrap ones head around, but it's really golden in its > straight-forwardness. I'd almost say its a doc problem if anything. > > ... > > Now, looking at my code again, I see that the postgresql read and write > functions do have a signature exactly like the normal read/write > functions. So your suggestion might just plug'n'play. Hey, cool. Do > your worst :) OK, thanks for your feedback. Maybe it is worth keeping. > Ps. I've got: > > do { > // Read in more data when emptying the in-buffer > if (bufs.avail_in == 0 && ! bufs.eof_in) { > total_read_delta += bufs.avail_in = > lo_read(fd_delta, inBuffer, bufSize); > bufs.next_in = inBuffer; > if (total_read_delta == length_delta) > bufs.eof_in = 1; > > elog(DEBUG, "Reading %d bytes (eof %d)", > bufs.avail_in, bufs.eof_in); > } > > // Iterate the job > ok = rs_job_iter (job, &bufs); > > // Write out data when filling the out-buffer > if (bufs.avail_out == 0 || bufs.eof_in) { > int bytes = lo_write(fd_out, outBuffer, > bufs.next_out - outBuffer); > bufs.next_out = outBuffer; > bufs.avail_out = bufSize; > elog(DEBUG, "Writing %d bytes (eof %d)", bytes, > bufs.eof_in); > } > > if (ok == RS_DONE) > break; > if (ok != RS_BLOCKED) > elog(ERROR, "An error occured creating the patch > (%s)", rs_strerror(ok)); > } while (ok == RS_BLOCKED); So in what I was suggesting, you would basically write little shims like this: rs_result lo_write_shim(void *opaque, const char *buf, size_t len, size_t *written) { int bytes; bytes = lo_write(*(int *) opaque, buf, len); /* handle errors? */ *written = bytes; return RS_DONE; } rs_result lo_read_shim(void *opaque, char *buf, size_t len, size_t *read_bytes) { int bytes = lo_read(*(int*) opaque, buf, len); *read_bytes = bytes; /* does lo_read tell you about EOF? */ return RS_DONE; } ..... result = rs_delta_begin(&job, sigs, lo_read_shim, &fd_in, lo_write_shim, &fd_out); if (result != RS_OK) return result; while ((result = rs_job_run(job)) == RS_BLOCKED) ; I think that will not be noticeably slower, and it is considerably easier to get right. -- Martin
signature.asc
(application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iD8DBQFAMVUWPGPKP6Cz6IsRAl07AJ0cd4Eq58A4NdU2hhWuwNRgtL+nZQCZAeeW aOcrOgGiXmdNJ3NHZZpsEYg= =CQyJ -----END PGP SIGNATURE-----