You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by al...@apache.org on 2019/07/08 22:02:48 UTC

[asterixdb] branch master updated: [ASTERIXDB-2607][RT][*DB] Fix detecting duplicate fields in record construction

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 <al...@gmail.com>
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 <je...@fulliautomatix.ics.uci.edu>
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Ali Alsuliman <al...@gmail.com>
    Reviewed-by: Dmitry Lychagin <dm...@couchbase.com>
---
 .../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 {