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;
107 if( dlen == 0 || chindex >= chunks.size() )
118 auto st = socket.
ReadV(
iov.
data() + iovindex, iovcnt, nbbts );
127 while( nbbts > 0 && dlen > 0 && chindex < chunks.size() );
137 inline static int max_iovcnt()
147 inline void addiov(
char *&buf,
size_t len )
150 iov.back().iov_base = buf;
151 iov.back().iov_len = len;
159 inline void addiov(
char *&buf, uint32_t len, uint32_t &dleft )
161 if( len > dleft ) len = dleft;
170 inline static uint32_t CalcIOVSize( uint32_t dleft )
172 uint32_t ret = ( dleft / PageWithDigest + 2 ) * 2;
173 return ( ret > uint32_t( max_iovcnt() ) ? max_iovcnt() : ret );
179 uint32_t CalcRdSize()
182 uint32_t dleft = dlen;
184 uint32_t pgspace = chunks[chindex].length - choff;
186 uint32_t dgspace =
sizeof( uint32_t ) * (digests.size() - dgindex ) - dgoff;
187 if( dleft > pgspace + dgspace )
188 dleft = pgspace + dgspace;
199 uint32_t dleft = CalcRdSize();
203 iov.reserve( CalcIOVSize( dleft ) );
205 ChunkInfo ch = chunks[chindex];
206 char* pgbuf =
static_cast<char*
>( ch.buffer ) + choff;
207 uint64_t rdoff = ch.offset + choff;
208 char* dgbuf =
reinterpret_cast<char*
>( digests.data() + dgindex ) + dgoff;
210 uint32_t fdglen =
sizeof( uint32_t ) - dgoff;
211 addiov( dgbuf, fdglen, dleft );
212 if( dleft == 0 || iovcnt >= max_iovcnt() )
216 addiov( pgbuf, fpglen, dleft );
217 if( dleft == 0 || iovcnt >= max_iovcnt() )
220 size_t fullpgs = dleft / PageWithDigest;
221 for(
size_t i = 0; i < fullpgs; ++i )
223 addiov( dgbuf,
sizeof( uint32_t ), dleft );
224 if( dleft == 0 || iovcnt >= max_iovcnt() )
227 if( dleft == 0 || iovcnt >= max_iovcnt() )
231 uint32_t ldglen =
sizeof( uint32_t );
232 addiov( dgbuf, ldglen, dleft );
233 if( dleft == 0 || iovcnt >= max_iovcnt() )
236 addiov( pgbuf, dleft, dleft );
242 inline void shift(
void *&buffer,
size_t nbbts )
244 char *buf =
static_cast<char*
>( buffer );
254 inline void shiftdgbuf( uint32_t &btsread )
256 if(
iov[iovindex].iov_len > btsread )
258 iov[iovindex].iov_len -= btsread;
259 shift(
iov[iovindex].iov_base, btsread );
265 btsread -=
iov[iovindex].iov_len;
266 iov[iovindex].iov_len = 0;
268 digests[dgindex] = ntohl( digests[dgindex] );
279 inline void shiftpgbuf( uint32_t &btsread )
281 if(
iov[iovindex].iov_len > btsread )
283 iov[iovindex].iov_len -= btsread;
284 shift(
iov[iovindex].iov_base, btsread );
290 btsread -=
iov[iovindex].iov_len;
291 choff +=
iov[iovindex].iov_len;
292 iov[iovindex].iov_len = 0;
300 void ShiftIOV( uint32_t btsread )
303 if( iovindex % 2 == 0 )
304 shiftdgbuf( btsread );
309 shiftpgbuf( btsread );
310 if( btsread == 0 )
break;
312 shiftdgbuf( btsread );
318 if( choff >= chunks[chindex].length )
326 std::vector<uint32_t> &digests;
335 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