21 : segment_size(segsize),
22 segment_count(segcount),
23 segment_lookback(lookback),
26 #if VERBOSE_ASYNC_FILEBUF
27 std::cout <<
THIS_ASYNCFB <<
"async_filebuf::async_filebuf(" << segsize <<
"," << segcount <<
"," << lookback <<
")" << std::endl;
30 std::string errmsg(
"async_filebuf error - insufficient"
31 " segment count for look-back.");
32 std::cerr << errmsg << std::endl;
33 throw std::range_error(errmsg);
36 buffer =
new char[bufsize];
42 #if VERBOSE_ASYNC_FILEBUF
43 std::cout <<
THIS_ASYNCFB <<
"async_filebuf::~async_filebuf()" << std::endl;
52 #if VERBOSE_ASYNC_FILEBUF
53 std::cout <<
THIS_ASYNCFB <<
"async_filebuf::readloop_initiate()" << std::endl;
75 #if VERBOSE_ASYNC_FILEBUF
76 std::cout <<
THIS_ASYNCFB <<
"async_filebuf::readloop_terminate()" << std::endl;
80 std::streampos pos =
getpos();
89 std::filebuf::seekpos(pos, std::ios::in);
102 #if VERBOSE_ASYNC_FILEBUF
103 std::cout <<
THIS_ASYNCFB <<
"async_filebuf::readloop()" << std::endl;
116 segment_pos[seg] = this->std::filebuf::seekoff(0, std::ios::cur, std::ios::in);
119 segment_len[seg] = std::filebuf::xsgetn(sbase, nreq);
130 #if VERBOSE_ASYNC_FILEBUF
131 std::cout <<
THIS_ASYNCFB <<
"async_filebuf::underflow()" << std::endl;
137 return std::filebuf::underflow();
156 if (segment_len[seg] == 0)
162 std::ios::openmode which)
164 #if VERBOSE_ASYNC_FILEBUF
165 std::cout <<
THIS_ASYNCFB <<
"async_filebuf::seekoff(" << off <<
"," << way <<
"," << which <<
")" << std::endl;
168 if (way == std::ios::beg)
170 else if (way == std::ios::cur)
175 return this->std::filebuf::seekoff(off, way, which);
180 #if VERBOSE_ASYNC_FILEBUF
181 std::cout <<
THIS_ASYNCFB <<
"async_filebuf::seekpos(" << pos <<
"," << which <<
")" << std::endl;
184 return this->std::filebuf::seekpos(pos, which);
186 if (pos < std::streampos(0))
187 pos = std::streampos(0);
188 std::streampos curpos =
getpos();
192 return this->std::filebuf::seekpos(pos, which);
202 return this->std::filebuf::seekpos(pos, which);
209 return std::streampos(std::streamoff(-1));
221 #if VERBOSE_ASYNC_FILEBUF
222 std::cout <<
THIS_ASYNCFB <<
"async_filebuf::xsgetn(s," << n <<
")" << std::endl;
225 return std::filebuf::xsgetn(s,n);
228 std::streamsize nleft=n;
232 nbuf = (nbuf < nleft)? nbuf : nleft;
233 memcpy(s, buffer_gptr, nbuf);
234 #if VERBOSE_ASYNC_FILEBUF
235 std::cout <<
THIS_ASYNCFB <<
"memcpy(d, s, " << nbuf <<
")" << std::endl;
238 shadow_ifs.seekg(
getpos());
239 char *shadowbuf =
new char[nbuf];
240 if (shadow_ifs.read(shadowbuf, nbuf) && shadow_ifs.gcount() == nbuf) {
241 for (
int i=0; i<nbuf; ++i) {
242 if (shadowbuf[i] != buffer_gptr[i]) {
243 std::cerr <<
"Error in async_filebuf::xsgetn - "
244 "data read from buffer does not match "
245 "what reading directly from the file "
246 "gives at the same offset! Cannot continue."
253 std::cerr <<
"Error in async_filebuf::xsgetn - "
254 "error reading from the shadow ifstream input. "
273 int async_filebuff_disable_for_mac_osx = 0;
std::vector< segment_state > segment_cond
virtual std::streampos seekpos(std::streampos pos, std::ios::openmode which)
std::condition_variable readloop_wake
std::condition_variable readloop_woke
std::thread * readloop_thread
async_filebuf(int segsize=1000000, int segcount=3, int lookback=1)
std::vector< std::streampos > segment_pos
virtual std::streamsize xsgetn(char *s, std::streamsize n)
std::vector< std::streamsize > segment_len
virtual std::streambuf * setbuf(char *s, std::streamsize n)
virtual std::streampos seekoff(std::streamoff off, std::ios::seekdir way, std::ios::openmode which)