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

kturner pushed a commit to branch 3.1
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/3.1 by this push:
     new cdf30d0667 Adds ByteSequence constructors to Key (#5327)
cdf30d0667 is described below

commit cdf30d0667cf67bd3bdf04f7b3b24cd1037b63f9
Author: Keith Turner <ktur...@apache.org>
AuthorDate: Fri Feb 14 17:17:54 2025 -0500

    Adds ByteSequence constructors to Key (#5327)
    
    Key has methods to get data as ByteSequences but no methods to create
    keys using ByteSequence.  This leads to either using Text or
    ByteSequence plus byte[].  Text always does an intermediate copy and
    ByteSequence plus byte[] is cumbersome.  These new method make it easier
    to efficiently create a new Key from an existing Key w/ less code and
    less copying of data.
    
    Co-authored-by: Christopher Tubbs <ctubb...@apache.org>
---
 .../java/org/apache/accumulo/core/data/Key.java    | 57 ++++++++++++++
 .../org/apache/accumulo/core/data/KeyBuilder.java  | 88 ++++++++++++++++++++++
 .../org/apache/accumulo/core/data/KeyTest.java     | 50 ++++++++++++
 3 files changed, 195 insertions(+)

diff --git a/core/src/main/java/org/apache/accumulo/core/data/Key.java 
b/core/src/main/java/org/apache/accumulo/core/data/Key.java
index d6f0ebccf7..6344d4bb70 100644
--- a/core/src/main/java/org/apache/accumulo/core/data/Key.java
+++ b/core/src/main/java/org/apache/accumulo/core/data/Key.java
@@ -552,6 +552,63 @@ public class Key implements WritableComparable<Key>, 
Cloneable {
         new Text(cv.getExpression()), ts);
   }
 
+  /**
+   * Creates a key with the specified row, the specified column family, the 
specified column
+   * qualifier, the specified column visibility, the specified timestamp, and 
delete marker false.
+   * This constructor creates a copy of the fields.
+   * <p>
+   * To avoid copying, use
+   * {@link Key#Key(byte[] row, byte[] cf, byte[] cq, byte[] cv, long ts, 
boolean deleted, boolean copy)}
+   * instead.
+   *
+   * @see #builder()
+   * @since 3.1.0
+   */
+  public Key(ByteSequence row, ByteSequence cf, ByteSequence cq, ByteSequence 
cv, long ts) {
+    byte[] rowBytes, cfBytes, cqBytes, cvBytes;
+    int rowOffset, cfOffset, cqOffset, cvOffset;
+    int rowLen, cfLen, cqLen, cvLen;
+
+    if (row.isBackedByArray()) {
+      rowBytes = row.getBackingArray();
+      rowOffset = row.offset();
+    } else {
+      rowBytes = row.toArray();
+      rowOffset = 0;
+    }
+    rowLen = row.length();
+
+    if (cf.isBackedByArray()) {
+      cfBytes = cf.getBackingArray();
+      cfOffset = cf.offset();
+    } else {
+      cfBytes = cf.toArray();
+      cfOffset = 0;
+    }
+    cfLen = cf.length();
+
+    if (cq.isBackedByArray()) {
+      cqBytes = cq.getBackingArray();
+      cqOffset = cq.offset();
+    } else {
+      cqBytes = cq.toArray();
+      cqOffset = 0;
+    }
+    cqLen = cq.length();
+
+    if (cv.isBackedByArray()) {
+      cvBytes = cv.getBackingArray();
+      cvOffset = cv.offset();
+    } else {
+      cvBytes = cv.toArray();
+      cvOffset = 0;
+    }
+    cvLen = cv.length();
+
+    init(rowBytes, rowOffset, rowLen, cfBytes, cfOffset, cfLen, cqBytes, 
cqOffset, cqLen, cvBytes,
+        cvOffset, cvLen, ts, false, true);
+  }
+
   private byte[] followingArray(byte[] ba) {
     byte[] fba = new byte[ba.length + 1];
     System.arraycopy(ba, 0, fba, 0, ba.length);
diff --git a/core/src/main/java/org/apache/accumulo/core/data/KeyBuilder.java 
b/core/src/main/java/org/apache/accumulo/core/data/KeyBuilder.java
index b9798ab64f..b49d9f76c9 100644
--- a/core/src/main/java/org/apache/accumulo/core/data/KeyBuilder.java
+++ b/core/src/main/java/org/apache/accumulo/core/data/KeyBuilder.java
@@ -100,6 +100,15 @@ public class KeyBuilder {
      */
     ColumnFamilyStep row(final byte[] row);
 
+    /**
+     * Set the row of the {@link Key} that this builder will build to the 
parameter.
+     *
+     * @param row the row to use for the key
+     * @return this builder
+     * @since 3.1.0
+     */
+    ColumnFamilyStep row(final ByteSequence row);
+
     /**
      * Set the row of the {@link Key} that this builder will build to the 
parameter.
      *
@@ -136,6 +145,15 @@ public class KeyBuilder {
      */
     ColumnQualifierStep family(final byte[] columnFamily);
 
+    /**
+     * Set the column family of the {@link Key} that this builder will build 
to the parameter.
+     *
+     * @param columnFamily the column family to use for the {@link Key}
+     * @return this builder
+     * @since 3.1.0
+     */
+    ColumnQualifierStep family(final ByteSequence columnFamily);
+
     /**
      * Set the column family of the {@link Key} that this builder will build 
to the parameter.
      *
@@ -180,6 +198,15 @@ public class KeyBuilder {
      */
     ColumnVisibilityStep qualifier(final byte[] columnQualifier);
 
+    /**
+     * Set the column qualifier of the {@link Key} that this builder will 
build to the parameter.
+     *
+     * @param columnQualifier the column qualifier to use for the {@link Key}
+     * @return this builder
+     * @since 3.1.0
+     */
+    ColumnVisibilityStep qualifier(final ByteSequence columnQualifier);
+
     /**
      * Set the column qualifier of the {@link Key} that this builder will 
build to the parameter.
      *
@@ -225,6 +252,15 @@ public class KeyBuilder {
      */
     Build visibility(final byte[] columnVisibility);
 
+    /**
+     * Set the column qualifier of the {@link Key} that this builder will 
build to the parameter.
+     *
+     * @param columnVisibility the column visibility to use for the {@link Key}
+     * @return this builder
+     * @since 3.1.0
+     */
+    Build visibility(ByteSequence columnVisibility);
+
     /**
      * Set the column qualifier of the {@link Key} that this builder will 
build to the parameter.
      *
@@ -312,6 +348,19 @@ public class KeyBuilder {
       return row(row, 0, row.length);
     }
 
+    @Override
+    public ColumnFamilyStep row(ByteSequence row) {
+      if (row.isBackedByArray()) {
+        this.row = row.getBackingArray();
+        this.rowOffset = row.offset();
+      } else {
+        this.row = row.toArray();
+        this.rowOffset = 0;
+      }
+      this.rowLength = row.length();
+      return this;
+    }
+
     @Override
     public ColumnFamilyStep row(final Text row) {
       return row(row.getBytes(), 0, row.getLength());
@@ -335,6 +384,19 @@ public class KeyBuilder {
       return family(family, 0, family.length);
     }
 
+    @Override
+    public ColumnQualifierStep family(ByteSequence columnFamily) {
+      if (columnFamily.isBackedByArray()) {
+        this.family = columnFamily.getBackingArray();
+        this.familyOffset = columnFamily.offset();
+      } else {
+        this.family = columnFamily.toArray();
+        this.familyOffset = 0;
+      }
+      this.familyLength = columnFamily.length();
+      return this;
+    }
+
     @Override
     public ColumnQualifierStep family(Text family) {
       return family(family.getBytes(), 0, family.getLength());
@@ -358,6 +420,19 @@ public class KeyBuilder {
       return qualifier(qualifier, 0, qualifier.length);
     }
 
+    @Override
+    public ColumnVisibilityStep qualifier(ByteSequence columnQualifier) {
+      if (columnQualifier.isBackedByArray()) {
+        this.qualifier = columnQualifier.getBackingArray();
+        this.qualifierOffset = columnQualifier.offset();
+      } else {
+        this.qualifier = columnQualifier.toArray();
+        this.qualifierOffset = 0;
+      }
+      this.qualifierLength = columnQualifier.length();
+      return this;
+    }
+
     @Override
     public ColumnVisibilityStep qualifier(Text qualifier) {
       return qualifier(qualifier.getBytes(), 0, qualifier.getLength());
@@ -381,6 +456,19 @@ public class KeyBuilder {
       return visibility(visibility, 0, visibility.length);
     }
 
+    @Override
+    public Build visibility(ByteSequence columnVisibility) {
+      if (columnVisibility.isBackedByArray()) {
+        this.visibility = columnVisibility.getBackingArray();
+        this.visibilityOffset = columnVisibility.offset();
+      } else {
+        this.visibility = columnVisibility.toArray();
+        this.visibilityOffset = 0;
+      }
+      this.visibilityLength = columnVisibility.length();
+      return this;
+    }
+
     @Override
     public Build visibility(Text visibility) {
       return visibility(visibility.getBytes(), 0, visibility.getLength());
diff --git a/core/src/test/java/org/apache/accumulo/core/data/KeyTest.java 
b/core/src/test/java/org/apache/accumulo/core/data/KeyTest.java
index 4751f45ef6..7b36606b55 100644
--- a/core/src/test/java/org/apache/accumulo/core/data/KeyTest.java
+++ b/core/src/test/java/org/apache/accumulo/core/data/KeyTest.java
@@ -328,4 +328,54 @@ public class KeyTest {
         new Key(new Text(row), new Text(colFamily), new Text(colQualifier), 
colVisibility2, ts);
     assertEquals(bytesColVisibilityKey2, textColVisibilityKey2);
   }
+
+  private static class TestByteSequence extends ArrayByteSequence {
+
+    private static final long serialVersionUID = 1234L;
+
+    public TestByteSequence(String s) {
+      super(s);
+    }
+
+    @Override
+    public boolean isBackedByArray() {
+      return false;
+    }
+  }
+
+  @Test
+  public void testByteSequenceConstructor() {
+    var row1 = new ArrayByteSequence("Row");
+    var row2 = new ArrayByteSequence("TheRowData").subSequence(3, 6);
+    var row3 = new TestByteSequence("Row");
+
+    var fam1 = new ArrayByteSequence("Family");
+    var fam2 = new ArrayByteSequence("SomeFamilyData").subSequence(4, 10);
+    var fam3 = new TestByteSequence("Family");
+
+    var qual1 = new ArrayByteSequence("Qual");
+    var qual2 = new ArrayByteSequence("TheQualData").subSequence(3, 7);
+    var qual3 = new TestByteSequence("Qual");
+
+    var vis1 = new ArrayByteSequence("Vis");
+    var vis2 = new ArrayByteSequence("AVisData").subSequence(1, 4);
+    var vis3 = new TestByteSequence("Vis");
+
+    var expectedKey = new Key("Row", "Family", "Qual", "Vis", 4);
+
+    for (var r : List.of(row1, row2, row3)) {
+      for (var f : List.of(fam1, fam2, fam3)) {
+        for (var q : List.of(qual1, qual2, qual3)) {
+          for (var v : List.of(vis1, vis2, vis3)) {
+            var actualKey = new Key(r, f, q, v, 4);
+            assertEquals(expectedKey, actualKey);
+            var actualKey2 =
+                
Key.builder().row(r).family(f).qualifier(q).visibility(v).timestamp(4).build();
+            assertEquals(expectedKey, actualKey2);
+          }
+        }
+      }
+    }
+
+  }
 }

Reply via email to