Skip to content

Commit a8c5970

Browse files
authored
JAPI-498 DFSClient: Reading long varstrings corrupted (hpcc-systems#597)
* JAPI-498 DFSClient: Reading long varstrings corrupted - Modified BinaryRecordReader to correctly handle read ahead in varstr - Added a long string test Signed-off-by: James McMullan [email protected] * Code review changes Signed-off-by: James McMullan [email protected]
1 parent a29c93f commit a8c5970

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

dfsclient/src/main/java/org/hpccsystems/dfs/client/BinaryRecordReader.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,7 @@ private String getNullTerminatedString(HpccSrcType stype) throws IOException
959959
throw new IOException("Error, unexpected EOS while constructing UTF16 string.");
960960
}
961961

962-
readSize = (readSize / 2) * 2;
962+
readSize = ((readSize + 1) / 2) * 2;
963963
if (readSize > OPTIMIZED_STRING_READ_AHEAD)
964964
{
965965
readSize = OPTIMIZED_STRING_READ_AHEAD;
@@ -970,7 +970,7 @@ private String getNullTerminatedString(HpccSrcType stype) throws IOException
970970

971971
for (int j = 0; j < readSize-1; j += 2)
972972
{
973-
if (scratchBuffer[j] == '\0' && scratchBuffer[j + 1] == '\0')
973+
if (scratchBuffer[strByteLen + j] == '\0' && scratchBuffer[strByteLen + j + 1] == '\0')
974974
{
975975
eosLocation = j;
976976
break;
@@ -1018,7 +1018,7 @@ private String getNullTerminatedString(HpccSrcType stype) throws IOException
10181018

10191019
for (int j = 0; j < readSize; j++)
10201020
{
1021-
if (scratchBuffer[j] == '\0')
1021+
if (scratchBuffer[strByteLen + j] == '\0')
10221022
{
10231023
eosLocation = j;
10241024
break;

dfsclient/src/test/java/org/hpccsystems/dfs/client/DFSReadWriteTest.java

+41-1
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,6 @@ public void getNullMetadataTest() throws Exception
276276
assertNull("Meta should be null for nonexistent file",meta);
277277
}
278278

279-
280279
private static final String ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
281280
private static final SecureRandom RANDOM = new SecureRandom();
282281

@@ -376,6 +375,47 @@ public void unsigned8ToDecimalTest() throws Exception
376375
}
377376
}
378377

378+
@Test
379+
public void longStringTest() throws Exception
380+
{
381+
// Create a large record dataset
382+
FieldDef[] fieldDefs = new FieldDef[4];
383+
fieldDefs[0] = new FieldDef("LongVarUnicode", FieldType.VAR_STRING, "", 4, false, false, HpccSrcType.UTF16LE, new FieldDef[0]);
384+
fieldDefs[1] = new FieldDef("LongUnicode", FieldType.STRING, "", 64, true, false, HpccSrcType.UTF16LE, new FieldDef[0]);
385+
fieldDefs[2] = new FieldDef("LongVarString", FieldType.VAR_STRING, "", 4, false, false, HpccSrcType.SINGLE_BYTE_CHAR, new FieldDef[0]);
386+
fieldDefs[3] = new FieldDef("LongString", FieldType.STRING, "", 64, true, false, HpccSrcType.SINGLE_BYTE_CHAR, new FieldDef[0]);
387+
FieldDef recordDef = new FieldDef("RootRecord", FieldType.RECORD, "rec", 4, false, false, HpccSrcType.LITTLE_ENDIAN, fieldDefs);
388+
389+
List<HPCCRecord> originalRecords = new ArrayList<HPCCRecord>();
390+
for (int i = 0; i < 10; i++)
391+
{
392+
Object[] fields = new Object[4];
393+
fields[0] = generateRandomString(1024);
394+
fields[1] = generateRandomString(64);
395+
fields[2] = generateRandomString(1024);
396+
fields[3] = generateRandomString(64);
397+
HPCCRecord record = new HPCCRecord(fields, recordDef);
398+
originalRecords.add(record);
399+
}
400+
401+
String datasetName = "benchmark::long_string::10rows";
402+
writeFile(originalRecords, datasetName, recordDef,connTO);
403+
404+
HPCCFile file = new HPCCFile(datasetName, connString , hpccUser, hpccPass);
405+
List<HPCCRecord> readRecords = readFile(file, connTO, false);
406+
if (readRecords.size() < 10)
407+
{
408+
Assert.fail("Failed to read " + datasetName + " dataset");
409+
}
410+
411+
for (int i = 0; i < 10; i++)
412+
{
413+
HPCCRecord originalRecord = originalRecords.get(i);
414+
HPCCRecord readRecord = originalRecords.get(i);
415+
Assert.assertEquals(originalRecord, readRecord);
416+
}
417+
}
418+
379419
@Test
380420
public void numericOverflowTest() throws Exception
381421
{

0 commit comments

Comments
 (0)