This is an automated email from the ASF dual-hosted git repository.

alsuliman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new dc4e335  [ASTERIXDB-2607][RT][*DB] Fix detecting duplicate fields in 
record construction
dc4e335 is described below

commit dc4e33596bc83a7886e3a513bc2be78123c0778a
Author: Ali Alsuliman <[email protected]>
AuthorDate: Mon Jul 8 00:22:37 2019 -0700

    [ASTERIXDB-2607][RT][*DB] Fix detecting duplicate fields in record 
construction
    
    - user model changes: no
    - storage format changes: no
    - interface changes: no
    
    Details:
    Fix detecting duplicate field names in record construction.
    
    Change-Id: Ib11647cee4e6dd07f04b9e91ce03cb72f293bcb2
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/3479
    Contrib: Jenkins <[email protected]>
    Integration-Tests: Jenkins <[email protected]>
    Tested-by: Jenkins <[email protected]>
    Reviewed-by: Ali Alsuliman <[email protected]>
    Reviewed-by: Dmitry Lychagin <[email protected]>
---
 .../org/apache/asterix/builders/RecordBuilder.java  | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/RecordBuilder.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/RecordBuilder.java
index 1273ed1..742cfb3 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/RecordBuilder.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/builders/RecordBuilder.java
@@ -218,16 +218,25 @@ public class RecordBuilder implements IARecordBuilder {
                 openPartOffsetArray = new byte[openPartOffsetArraySize];
             }
 
+            // field names with the same hash code should be adjacent to each 
other after sorting
             Arrays.sort(this.openPartOffsets, 0, numberOfOpenFields);
             if (numberOfOpenFields > 1) {
                 byte[] openBytes = openPartOutputStream.getByteArray();
-                for (int i = 1; i < numberOfOpenFields; i++) {
-                    if (utf8Comparator.compare(openBytes, (int) 
openPartOffsets[i - 1], openFieldNameLengths[i - 1],
-                            openBytes, (int) openPartOffsets[i], 
openFieldNameLengths[i]) == 0) {
+                for (int i = 0, k = 1; i < numberOfOpenFields - 1;) {
+                    if (utf8Comparator.compare(openBytes, (int) 
openPartOffsets[i], openFieldNameLengths[i], openBytes,
+                            (int) openPartOffsets[k], openFieldNameLengths[k]) 
== 0) {
                         String field = utf8SerDer.deserialize(new 
DataInputStream(new ByteArrayInputStream(openBytes,
                                 (int) openPartOffsets[i], 
openFieldNameLengths[i])));
                         throw new HyracksDataException(
-                                "Open fields " + (i - 1) + " and " + i + " 
have the same field name \"" + field + "\"");
+                                "Open fields " + i + " and " + k + " have the 
same field name \"" + field + "\"");
+                    }
+                    if (sameHashes(openPartOffsets, i, k) && k < 
numberOfOpenFields - 1) {
+                        // keep comparing the current field i with the next 
field k
+                        k++;
+                    } else {
+                        // the current field i has no duplicates; move to the 
adjacent one
+                        i++;
+                        k = i + 1;
                     }
                 }
             }
@@ -249,6 +258,10 @@ public class RecordBuilder implements IARecordBuilder {
         writeRecord(out, writeTypeTag, h, recordLength);
     }
 
+    private static boolean sameHashes(long[] hashAndOffset, int fieldId1, int 
fieldId2) {
+        return (int) (hashAndOffset[fieldId1] >>> 32) == (int) 
(hashAndOffset[fieldId2] >>> 32);
+    }
+
     private void writeRecord(DataOutput out, boolean writeTypeTag, int 
headerSize, int recordLength)
             throws HyracksDataException {
         try {

Reply via email to