Skip to content

Commit f45e056

Browse files
committed
io: test long range Read/WriteObjectAny
1 parent 1687042 commit f45e056

1 file changed

Lines changed: 102 additions & 1 deletion

File tree

io/io/test/testByteCount.cxx

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <vector>
66

77

8-
int testByteCount()
8+
int unittestByteCount()
99
{
1010
int errors = 0;
1111
unsigned int expectedByteCounts = 1;
@@ -124,3 +124,104 @@ int testByteCount()
124124
std::cerr << "The end.\n";
125125
return errors;
126126
}
127+
128+
struct LargeByteCountsFixture {
129+
std::size_t fSize{0};
130+
void resize(size_t size) {
131+
fSize = size;
132+
}
133+
void Streamer(TBuffer &b) {
134+
// Bare minimum to trigger the large byte count mechanism,
135+
// we don't care about the content of the data.
136+
if (b.IsReading()) {
137+
b >> fSize;
138+
b.SetBufferOffset(b.GetCurrent() - b.Buffer() + fSize);
139+
} else {
140+
b << fSize;
141+
b.SetBufferOffset(b.GetCurrent() - b.Buffer() + fSize);
142+
}
143+
}
144+
};
145+
146+
#ifdef __ROOTCLING__
147+
#pragma link C++ class LargeByteCountsFixture-;
148+
#endif
149+
150+
int readAndCheck(const std::string &msg, TBufferFile &b, size_t expected_size)
151+
{
152+
// Same as b >> ptr;
153+
auto obj = b.ReadObjectAny(TClass::GetClass(typeid(LargeByteCountsFixture)));
154+
if (!obj) {
155+
std::cerr << msg << ": Failed to read back the object\n";
156+
return 1;
157+
} else {
158+
auto* readFixture = static_cast<LargeByteCountsFixture*>(obj);
159+
if (readFixture->fSize != expected_size ) {
160+
std::cerr << msg << ": The size of the data vectors do not match the original ones\n";
161+
delete readFixture;
162+
return 1;
163+
}
164+
delete readFixture;
165+
}
166+
return 0;
167+
}
168+
169+
170+
char *DoNothingAllocator(char* input, size_t, size_t)
171+
{
172+
// We 'could' check that the requested memory in under what we
173+
// preallocated.
174+
return input;
175+
}
176+
177+
int testReadWriteObjectAny()
178+
{
179+
int errors = 0;
180+
181+
// TBufferFile currently reject size larger than 2GB.
182+
// SetBufferOffset does not check against the size,
183+
// so we can provide and use a larger buffer.
184+
std::vector<char> databuffer{};
185+
databuffer.reserve(8 * 1024 * 1024 * 1024ll);
186+
TBufferFile b(TBuffer::kWrite, 8 * 1024 * 1024 * 1024ll - 100, databuffer.data(), false /* don't adopt */, DoNothingAllocator);
187+
188+
LargeByteCountsFixture fixture;
189+
fixture.resize(100); // Small object, should be written with the regular byte count mechanism.
190+
191+
auto startPos = b.GetCurrent() - b.Buffer();
192+
b.WriteObject(&fixture, false /* cacheReuse */);
193+
b.SetReadMode();
194+
b.SetBufferOffset(startPos);
195+
196+
errors += readAndCheck("Small object written in regular section", b, 100);
197+
198+
// Large object, should be written with the large byte count mechanism
199+
b.SetWriteMode();
200+
startPos = b.GetCurrent() - b.Buffer();
201+
fixture.resize(1024 * 1024 * 256); // 1GB of data
202+
b.WriteObject(&fixture, false /* cacheReuse */);
203+
b.SetReadMode();
204+
b.SetBufferOffset(startPos);
205+
errors += readAndCheck("Large object written in regular section", b, 1024 * 1024 * 256);
206+
207+
// Large object written in long range section, should be written with
208+
// the large byte count mechanism
209+
b.SetWriteMode();
210+
b.SetBufferOffset(4 * 1024 * 1024 * 1024ll + 100);
211+
startPos = b.GetCurrent() - b.Buffer();
212+
fixture.resize(1024 * 1024 * 256); // 1GB of data
213+
b.WriteObject(&fixture, false /* cacheReuse */);
214+
b.SetReadMode();
215+
b.SetBufferOffset(startPos);
216+
errors += readAndCheck("Large object written in long range section", b, 1024 * 1024 * 256);
217+
218+
return errors;
219+
}
220+
221+
222+
int testByteCount()
223+
{
224+
int res = unittestByteCount();
225+
res += testReadWriteObjectAny();
226+
return res;
227+
}

0 commit comments

Comments
 (0)