19 #ifndef SRC_XRDCL_XRDCLASYNCPAGEREADER_HH_
20 #define SRC_XRDCL_XRDCLASYNCPAGEREADER_HH_
29 #include <arpa/inet.h>
48 std::vector<uint32_t> &digests ) :
60 uint64_t rdoff = chunks.front().offset;
62 for(
auto &ch : chunks )
66 digests.resize( pgcnt );
82 rspoff = rsp->
info.pgread.offset;
84 uint64_t bufoff = rspoff - chunks[0].offset;
87 for( chindex = 0; chindex < chunks.size(); ++chindex )
89 if( chunks[chindex].length < bufoff )
91 bufoff -= chunks[chindex].length;
108 if( dlen == 0 || chindex >= chunks.size() )
119 auto st = socket.
ReadV(
iov.
data() + iovindex, iovcnt, nbbts );
128 while( nbbts > 0 && dlen > 0 && chindex < chunks.size() );
138 inline static int max_iovcnt()
148 inline void addiov(
char *&buf,
size_t len )
151 iov.back().iov_base = buf;
152 iov.back().iov_len = len;
160 inline void addiov(
char *&buf, uint32_t len, uint32_t &dleft )
162 if( len > dleft ) len = dleft;
171 inline static uint32_t CalcIOVSize( uint32_t dleft )
173 uint32_t ret = ( dleft / PageWithDigest + 2 ) * 2;
174 return ( ret > uint32_t( max_iovcnt() ) ? max_iovcnt() : ret );
180 uint32_t CalcRdSize()
183 uint32_t dleft = dlen;
185 uint32_t pgspace = chunks[chindex].length - choff;
187 uint32_t dgspace =
sizeof( uint32_t ) * (digests.size() - dgindex ) - dgoff;
188 if( dleft > pgspace + dgspace )
189 dleft = pgspace + dgspace;
200 uint32_t dleft = CalcRdSize();
204 iov.reserve( CalcIOVSize( dleft ) );
206 ChunkInfo ch = chunks[chindex];
207 char* pgbuf =
static_cast<char*
>( ch.buffer ) + choff;
208 uint64_t rdoff = ch.offset + choff;
209 char* dgbuf =
reinterpret_cast<char*
>( digests.data() + dgindex ) + dgoff;
211 uint32_t fdglen =
sizeof( uint32_t ) - dgoff;
212 addiov( dgbuf, fdglen, dleft );
213 if( dleft == 0 || iovcnt >= max_iovcnt() )
217 addiov( pgbuf, fpglen, dleft );
218 if( dleft == 0 || iovcnt >= max_iovcnt() )
221 size_t fullpgs = dleft / PageWithDigest;
222 for(
size_t i = 0; i < fullpgs; ++i )
224 addiov( dgbuf,
sizeof( uint32_t ), dleft );
225 if( dleft == 0 || iovcnt >= max_iovcnt() )
228 if( dleft == 0 || iovcnt >= max_iovcnt() )
232 uint32_t ldglen =
sizeof( uint32_t );
233 addiov( dgbuf, ldglen, dleft );
234 if( dleft == 0 || iovcnt >= max_iovcnt() )
237 addiov( pgbuf, dleft, dleft );
243 inline void shift(
void *&buffer,
size_t nbbts )
245 char *buf =
static_cast<char*
>( buffer );
255 inline void shiftdgbuf( uint32_t &btsread )
257 if(
iov[iovindex].iov_len > btsread )
259 iov[iovindex].iov_len -= btsread;
260 shift(
iov[iovindex].iov_base, btsread );
266 btsread -=
iov[iovindex].iov_len;
267 iov[iovindex].iov_len = 0;
269 digests[dgindex] = ntohl( digests[dgindex] );
280 inline void shiftpgbuf( uint32_t &btsread )
282 if(
iov[iovindex].iov_len > btsread )
284 iov[iovindex].iov_len -= btsread;
285 shift(
iov[iovindex].iov_base, btsread );
291 btsread -=
iov[iovindex].iov_len;
292 choff +=
iov[iovindex].iov_len;
293 iov[iovindex].iov_len = 0;
301 void ShiftIOV( uint32_t btsread )
304 if( iovindex % 2 == 0 )
305 shiftdgbuf( btsread );
310 shiftpgbuf( btsread );
311 if( btsread == 0 )
break;
313 shiftdgbuf( btsread );
319 if( choff >= chunks[chindex].length )
327 std::vector<uint32_t> &digests;
336 std::vector<iovec>
iov;
ServerResponseStatus status
struct ServerResponseBody_Status bdy
union ServerResponseV2::@1 info
XRootDStatus ReadV(iovec *iov, int iocnt, int &bytesRead)
static int csNum(off_t offs, int count)
Compute the required size of a checksum vector based on offset & length.
std::vector< ChunkInfo > ChunkList
List of chunks.
static const int PageSize