Code cleanup, especially in Utf8String class which is much improved.

This commit is contained in:
David Noble
2019-09-12 20:55:36 -07:00
parent 76e62cbd99
commit e942e2076c
14 changed files with 996 additions and 977 deletions

View File

@@ -23,7 +23,7 @@ public final class Reference<T> {
} }
public T get() { public T get() {
return value; return this.value;
} }
public void set(T value) { public void set(T value) {
@@ -41,7 +41,7 @@ public final class Reference<T> {
* @return {@code true} if there is a value present, otherwise {@code false} * @return {@code true} if there is a value present, otherwise {@code false}
*/ */
public boolean isPresent() { public boolean isPresent() {
return value != null; return this.value != null;
} }
/** /**
@@ -66,12 +66,12 @@ public final class Reference<T> {
return false; return false;
} }
return Objects.equals(value, ((Reference)other).value); return Objects.equals(this.value, ((Reference)other).value);
} }
@Override @Override
public String toString() { public String toString() {
return value == null ? "null" : value.toString(); return this.value == null ? "null" : this.value.toString();
} }
} }

View File

@@ -13,10 +13,13 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.node.JsonNodeType; import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.google.common.base.Objects;
import com.google.common.base.Suppliers;
import com.google.common.base.Utf8; import com.google.common.base.Utf8;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufHolder; import io.netty.buffer.ByteBufHolder;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.util.ByteProcessor;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -27,6 +30,7 @@ import java.util.Optional;
import java.util.Spliterator; import java.util.Spliterator;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.IntConsumer; import java.util.function.IntConsumer;
import java.util.function.Supplier;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
@@ -40,32 +44,49 @@ import static java.nio.charset.StandardCharsets.UTF_8;
@SuppressWarnings("UnstableApiUsage") @SuppressWarnings("UnstableApiUsage")
public final class Utf8String implements ByteBufHolder, CharSequence, Comparable<Utf8String> { public final class Utf8String implements ByteBufHolder, CharSequence, Comparable<Utf8String> {
public static final Utf8String EMPTY = new Utf8String(Unpooled.EMPTY_BUFFER, 0); public static final Utf8String EMPTY = new Utf8String(Unpooled.EMPTY_BUFFER);
public static final Utf8String NULL = new Utf8String(); public static final Utf8String NULL = new Utf8String(null);
private final ByteBuf buffer; private final ByteBuf buffer;
private final int length; private final Supplier<Integer> codePointCount;
private final Supplier<Integer> utf16CodeUnitCount;
private Utf8String() { private Utf8String(@Nullable final ByteBuf buffer) {
this.buffer = null;
this.length = -1;
}
private Utf8String(@Nonnull final ByteBuf buffer) { if (buffer == null) {
this(buffer, decodedLength(buffer)); this.buffer = null;
} this.codePointCount = Suppliers.memoize(() -> -1);
this.utf16CodeUnitCount = Suppliers.memoize(() -> -1);
return;
}
private Utf8String(@Nonnull final ByteBuf buffer, final int decodedLength) { if (buffer.writerIndex() == 0) {
checkNotNull(buffer, "expected non-null buffer"); this.buffer = Unpooled.EMPTY_BUFFER;
this.buffer = buffer.asReadOnly(); this.codePointCount = Suppliers.memoize(() -> 0);
this.length = decodedLength; this.utf16CodeUnitCount = Suppliers.memoize(() -> 0);
return;
}
this.buffer = buffer;
this.codePointCount = Suppliers.memoize(() -> {
final UTF8CodePointCounter counter = new UTF8CodePointCounter();
this.buffer.forEachByte(0, this.buffer.writerIndex(), counter);
return counter.value();
});
this.utf16CodeUnitCount = Suppliers.memoize(() -> {
final UTF16CodeUnitCounter counter = new UTF16CodeUnitCounter();
this.buffer.forEachByte(0, this.buffer.writerIndex(), counter);
return counter.value();
});
} }
/** /**
* {@code true} if the length of this instance is zero * {@code true} if the length of this instance is zero
*/ */
public final boolean isEmpty() { public final boolean isEmpty() {
return this.length == 0; return this.buffer != null && this.buffer.writerIndex() == 0;
} }
/** /**
@@ -92,10 +113,10 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
* Non-allocating enumeration of each code point in the UTF-8 stream * Non-allocating enumeration of each code point in the UTF-8 stream
*/ */
public final IntStream codePoints() { public final IntStream codePoints() {
if (this.length == 0) { if (this.buffer == null || this.buffer.writerIndex() == 0) {
return IntStream.empty(); return IntStream.empty();
} }
return StreamSupport.intStream(new CodePointIterable(this.buffer, this.length), false); return StreamSupport.intStream(new CodePointIterable(this.buffer, this.codePointCount.get()), false);
} }
@@ -130,7 +151,7 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
if (limit > 0) { if (limit > 0) {
final CodePointIterable iterable = new CodePointIterable(this.buffer, this.length); final CodePointIterable iterable = new CodePointIterable(this.buffer, this.utf16CodeUnitCount.get());
int index = 0; int index = 0;
for (int codePoint : iterable) { for (int codePoint : iterable) {
@@ -182,16 +203,16 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
/** /**
* Encoded length of this {@link Utf8String} * Encoded length of this {@link Utf8String}
* <p> * <p>
* This is the same value as would be returned by {@link String#getBytes()#length} with no time or space overhead. * This is the same value as would be returned by {@link String#getBytes()#utf16CodeUnitCount} with no time or space overhead.
* *
* @return encoded length of {@link Utf8String} * @return encoded length of {@link Utf8String}
*/ */
public final int encodedLength() { public final int encodedLength() {
return this.buffer.writerIndex(); return this.buffer == null ? 0 : this.buffer.writerIndex();
} }
public final boolean equals(ByteBuf other) { public final boolean equals(ByteBuf other) {
return this.buffer.equals(other); return Objects.equal(this.buffer, other);
} }
public final boolean equals(String other) { public final boolean equals(String other) {
@@ -202,33 +223,25 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
} }
public final boolean equals(Utf8String other) { public final boolean equals(Utf8String other) {
if (other == null) { if (this == other) {
return false;
}
if (other == this) {
return true; return true;
} }
return this.buffer.equals(other.buffer); if (null == other) {
return false;
}
return Objects.equal(this.buffer, other.buffer);
} }
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
if (other == null) { if (this == other) {
return false;
}
if (other == this) {
return true; return true;
} }
if (other instanceof ByteBuf) { if (null == other || this.getClass() != other.getClass()) {
return this.equals((ByteBuf)other); return false;
} }
if (other instanceof String) { Utf8String that = (Utf8String) other;
return this.equals((String)other); return this.utf16CodeUnitCount == that.utf16CodeUnitCount && Objects.equal(this.buffer, that.buffer);
}
if (other instanceof Utf8String) {
return this.equals((Utf8String)other);
}
return false;
} }
/** /**
@@ -247,11 +260,12 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
} }
/** /**
* Creates a new {@link Utf8String} from a {@link ByteBuf} without UTF-8 character validation * Creates a new {@link Utf8String} from a {@link ByteBuf} without UTF-8 character validation.
* <p> * <p>
* The {@link Utf8String} created retains the {@link ByteBuf}. (No data is transferred.) * The {@link Utf8String} created retains the {@link ByteBuf} and ensures it is read-only by calling
* {@link ByteBuf#asReadOnly}. No data is transferred.
* *
* @param buffer The {@link ByteBuf} to assign to the {@link Utf8String} created. * @param buffer a {@link ByteBuf} to assign to the {@link Utf8String} created.
* @return a new {@link Utf8String} * @return a new {@link Utf8String}
*/ */
@Nonnull @Nonnull
@@ -266,12 +280,13 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
} }
/** /**
* Returns the length of this character sequence * Returns the length of this character sequence.
* <p> * <p>
* The length is the number of Unicode characters in the sequence. * The length is the number of UTF-16 code units in the sequence. This is the same value as would be returned by
* {@link Utf8String#toUtf16()#length()} with no time or space overhead.
*/ */
public final int length() { public final int length() {
return this.length; return this.utf16CodeUnitCount.get();
} }
/** /**
@@ -285,10 +300,11 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
} }
/** /**
* Decreases the reference count by {@code 1} and deallocates this object if the reference count reaches at * Decreases the reference count by {@code 1}.
* {@code 0}.
* *
* @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated * The underlying storage for this instance is deallocated, if the reference count reaches {@code 0}.
*
* @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated.
*/ */
@Override @Override
public boolean release() { public boolean release() {
@@ -296,11 +312,12 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
} }
/** /**
* Decreases the reference count by the specified {@code decrement} and deallocates this object if the reference * Decreases the reference count by the specified {@code decrement}
* count reaches at {@code 0}.
* *
* @param decrement * The underlying storage for this instance is deallocated, if the reference count reaches {@code 0}.
* @return {@code true} if and only if the reference count became {@code 0} and this object has been deallocated *
* @param decrement the value to subtract from the reference count.
* @return {@code true} if and only if the reference count became {@code 0}.
*/ */
@Override @Override
public boolean release(int decrement) { public boolean release(int decrement) {
@@ -308,7 +325,7 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
} }
/** /**
* Returns a new {@link Utf8String} which contains the specified {@code content} * Returns a new {@link Utf8String} which contains the specified {@code content}.
* *
* @param content text of the {@link Utf8String} to be created. * @param content text of the {@link Utf8String} to be created.
*/ */
@@ -330,7 +347,7 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
} }
/** /**
* Duplicates this {@link Utf8String} * Duplicates this {@link Utf8String}.
* <p> * <p>
* This method returns a retained duplicate unlike {@link #duplicate()}. * This method returns a retained duplicate unlike {@link #duplicate()}.
* *
@@ -343,9 +360,8 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
@Override @Override
public CharSequence subSequence(int start, int end) { public CharSequence subSequence(int start, int end) {
checkArgument(start < 0 || end < 0 || start > end || end > this.length, "start: %s, end: %s", start, end); checkArgument(start < 0 || end < 0 || start > end || end > this.length(), "start: %s, end: %s", start, end);
// TODO: DANOBLE: compute buffer index for start and end character positions and use them in the slice return new Utf8String(this.buffer.slice(start, end));
return new Utf8String(this.buffer.slice(), end - start);
} }
@Override @Override
@@ -394,43 +410,34 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
checkState(count == length, "count: %s, length: %s", count, length); checkState(count == length, "count: %s, length: %s", count, length);
return new Utf8String(buffer, string.length()); return new Utf8String(buffer);
} }
private static int decodedLength(final ByteBuf buffer) { private static final class CodePointIterable extends UTF8CodePointGetter implements
Iterable<Integer>, Iterator<Integer>, Spliterator.OfInt {
final CodePointIterable iterable = new CodePointIterable(buffer, -1);
int decodedLength = 0;
for (int ignored : iterable) {
decodedLength++;
}
return decodedLength;
}
private static final class CodePointIterable implements Iterable<Integer>, Iterator<Integer>, Spliterator.OfInt {
private static final int CHARACTERISTICS = Spliterator.IMMUTABLE | Spliterator.NONNULL | Spliterator.ORDERED; private static final int CHARACTERISTICS = Spliterator.IMMUTABLE | Spliterator.NONNULL | Spliterator.ORDERED;
private final ByteBuf buffer; private final ByteBuf buffer;
private final int length; private final int codePointCount;
private int index;
CodePointIterable(final ByteBuf buffer, final int length) { private int start, length;
CodePointIterable(final ByteBuf buffer, final int codePointCount) {
this.codePointCount = codePointCount;
this.buffer = buffer; this.buffer = buffer;
this.length = length; this.start = 0;
this.index = 0; this.length = buffer.writerIndex();
} }
@Override @Override
public int characteristics() { public int characteristics() {
return this.length == -1 ? CHARACTERISTICS : CHARACTERISTICS | Spliterator.SIZED | Spliterator.SUBSIZED; return this.codePointCount == -1 ? CHARACTERISTICS : CHARACTERISTICS | Spliterator.SIZED | Spliterator.SUBSIZED;
} }
@Override @Override
public long estimateSize() { public long estimateSize() {
return this.length < 0 ? Long.MAX_VALUE : this.length; return this.codePointCount < 0 ? Long.MAX_VALUE : this.codePointCount;
} }
@Override @Override
@@ -440,7 +447,7 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return this.index < this.buffer.capacity(); return this.length > 0;
} }
@Override @Override
@@ -456,50 +463,10 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
throw new NoSuchElementException(); throw new NoSuchElementException();
} }
final int leadingByte = this.buffer.getByte(this.index++) & 0xFF; this.start = this.buffer.forEachByte(this.start, this.length, this);
this.length -= this.start;
// A 1-byte UTF-8 code point is a special case that covers the 7-bit ASCII character set return this.codePoint();
if (leadingByte < 0x80) {
return leadingByte;
}
// The initial byte of 2-, 3- and 4-byte UTF-8 code points start with 2, 3, or 4 one bits followed by a 0
// bit
final int codePoint;
if ((leadingByte & 0b1110_0000) == 0b1100_0000) {
// 110xxxxx 10xxxxxx => 0x00000080 - 0x000007FF
codePoint = ((leadingByte & 0b0001_1111) << 6) |
(this.buffer.getByte(this.index++) & 0b0011_1111);
} else if ((leadingByte & 0b1111_0000) == 0b1110_0000) {
// 1110xxxx 10xxxxxx 10xxxxxx => 0x00000800 - 0x0000FFFF
codePoint = ((leadingByte & 0b0000_1111) << 12) |
((this.buffer.getByte(this.index++) & 0b0011_1111) << 6) |
((this.buffer.getByte(this.index++) & 0b0011_1111));
} else if ((leadingByte & 0b1111_1000) == 0b1111_0000) {
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx => 0x00010000 - 0x001FFFFF
codePoint = ((leadingByte & 0b0000_0111) << 18) |
((this.buffer.getByte(this.index++) & 0b0011_1111) << 12) |
((this.buffer.getByte(this.index++) & 0b0011_1111) << 6) |
((this.buffer.getByte(this.index++) & 0b0011_1111));
} else {
// leading byte is improperly encoded and we'll detect that before returning
codePoint = leadingByte;
}
checkState(Character.isDefined(codePoint), "invalid character: %s", codePoint);
return codePoint;
} }
@Override @Override
@@ -563,4 +530,204 @@ public final class Utf8String implements ByteBufHolder, CharSequence, Comparable
generator.writeString(value.toString()); generator.writeString(value.toString());
} }
} }
/**
* A {@link ByteProcessor} used by to count the number of UTF-16 code units in a UTF-8 encoded string.
*
* This class makes use of the fact that code points that UTF-16 encodes with two 16-bit code units, UTF-8 encodes
* with 4 8-bit code units, and vice versa. Lead bytes are identified and counted. All other bytes are skipped.
* Code points are not validated. The {@link #process} method counts undefined leading bytes as an undefined UTF-16
* code unit to be replaced.
*
* @see <a href="https://tools.ietf.org/html/rfc3629">RFC 3629: UTF-8, a transformation format of ISO 10646</a>
*/
private static final class UTF16CodeUnitCounter implements ByteProcessor {
private int count = 0;
private int skip = 0;
@Override
public boolean process(byte value) throws Exception {
if (this.skip > 0) {
this.skip--;
} else {
final int leadingByte = value & 0xFF;
if (leadingByte < 0x7F) {
// UTF-8-1 = 0x00-7F
this.skip = 0;
this.count++;
} else if (0xC2 <= leadingByte && leadingByte <= 0xDF) {
// UTF8-8-2 = 0xC2-DF UTF8-tail
this.skip = 1;
this.count++;
} else if (0xE0 <= leadingByte && leadingByte <= 0xEF) {
// UTF-8-3 = 0xE0 0xA0-BF UTF8-tail / 0xE1-EC 2(UTF8-tail) / 0xED 0x80-9F UTF8-tail / 0xEE-EF 2(UTF8-tail)
this.skip = 2;
this.count++;
} else if (0xF0 <= leadingByte && leadingByte <= 0xF4) {
// UTF8-4 = 0xF0 0x90-BF 2( UTF8-tail ) / 0xF1-F3 3( UTF8-tail ) / 0xF4 0x80-8F 2( UTF8-tail )
this.skip = 3;
this.count += 2;
} else {
this.skip = 0;
this.count++;
}
}
return true;
}
public int value() {
return this.count;
}
}
/**
* A {@link ByteProcessor} used by to count the number of Unicode code points in a UTF-8 encoded string.
*
* Lead bytes are identified and counted. All other bytes are skipped. Code points are not validated. The
* {@link #process} method counts undefined lead bytes as a single code point to be replaced.
*
* @see <a href="https://tools.ietf.org/html/rfc3629">RFC 3629: UTF-8, a transformation format of ISO 10646</a>
*/
private static final class UTF8CodePointCounter implements ByteProcessor {
private int count = 0;
private int skip = 0;
@Override
public boolean process(byte value) {
if (this.skip > 0) {
this.skip--;
} else {
final int leadingByte = value & 0xFF;
if (leadingByte < 0x7F) {
// UTF-8-1 = 0x00-7F
this.skip = 0;
} else if (0xC2 <= leadingByte && leadingByte <= 0xDF) {
// UTF8-8-2 = 0xC2-DF UTF8-tail
this.skip = 1;
} else if (0xE0 <= leadingByte && leadingByte <= 0xEF) {
// UTF-8-3 = 0xE0 0xA0-BF UTF8-tail / 0xE1-EC 2(UTF8-tail) / 0xED 0x80-9F UTF8-tail / 0xEE-EF 2(UTF8-tail)
this.skip = 2;
} else if (0xF0 <= leadingByte && leadingByte <= 0xF4) {
// UTF8-4 = 0xF0 0x90-BF 2( UTF8-tail ) / 0xF1-F3 3( UTF8-tail ) / 0xF4 0x80-8F 2( UTF8-tail )
this.skip = 3;
} else {
// Undefined leading byte
this.skip = 0;
}
this.count++;
}
return true;
}
public int value() {
return this.count;
}
}
/**
* A {@link ByteProcessor} used to read a UTF-8 encoded string one Unicode code point at a time.
* <p>
* This {@link #process(byte)} method reads a single code point at a time. The first byte read following
* construction of an instance of this class must be a leading byte. This is used to determine the number of
* single-byte UTF-8 code units in the code point.
* <p>
* Code points are validated. The {@link #process(byte)} method returns the Unicode
* <a href="https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character">Replacement character</a>
* when an undefined code point is encountered.
*
* @see <a href="https://tools.ietf.org/html/rfc3629">RFC 3629: UTF-8, a transformation format of ISO 10646</a>
*/
private static class UTF8CodePointGetter implements ByteProcessor {
private static final int REPLACEMENT_CHARACTER = 0xFFFD;
private int codePoint = 0;
private int shift = -1;
/**
* Gets the next code unit in a UTF-8 code point sequence.
*
* @param value the next code unit in a UTF-8
*
* @return {@code true} if additional code units must be read to complete the code point; otherwise, if the
* code point is complete, a value of {@code false} is returned.
*/
@Override
public boolean process(byte value) {
switch (this.shift) {
default: {
// Next unit of code point sequence
this.codePoint |= (value & 0xFF << this.shift);
this.shift -= Byte.SIZE;
return true;
}
case 0: {
// End of code point sequence
this.codePoint |= value & 0xFF;
this.shift = -1;
if (!Character.isDefined(this.codePoint)) {
this.codePoint = REPLACEMENT_CHARACTER;
};
return false;
}
case -1: {
// Start of code point sequence
final int leadingByte = value & 0xFF;
if (leadingByte < 0x7F) {
// UTF-8-1 = 0x00-7F
this.codePoint = leadingByte;
return false;
}
if (0xC2 <= leadingByte && leadingByte <= 0xDF) {
// UTF8-8-2 = 0xC2-DF UTF8-tail
this.codePoint = leadingByte << Byte.SIZE;
this.shift = 0;
return true;
}
if (0xE0 <= leadingByte && leadingByte <= 0xEF) {
// UTF-8-3 = 0xE0 0xA0-BF UTF8-tail / 0xE1-EC 2(UTF8-tail) / 0xED 0x80-9F UTF8-tail / 0xEE-EF 2(UTF8-tail)
this.codePoint = leadingByte << 2 * Byte.SIZE;
this.shift = Byte.SIZE;
return true;
}
if (0xF0 <= leadingByte && leadingByte <= 0xF4) {
// UTF8-4 = 0xF0 0x90-BF 2( UTF8-tail ) / 0xF1-F3 3( UTF8-tail ) / 0xF4 0x80-8F 2( UTF8-tail )
this.codePoint = leadingByte << 3 * Byte.SIZE;
this.shift = 3 * Byte.SIZE;
return true;
}
this.codePoint = REPLACEMENT_CHARACTER;
return false;
}
}
}
/**
* Returns the value of the most-recently read code point.
*
* @return value of the most-recently read code point.
*/
int codePoint() {
return this.codePoint;
}
}
} }

View File

@@ -17,274 +17,278 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/ */
public final class UtfAnyString implements CharSequence, Comparable<UtfAnyString> { public final class UtfAnyString implements CharSequence, Comparable<UtfAnyString> {
private static final UtfAnyString EMPTY = new UtfAnyString(""); public static final UtfAnyString EMPTY = new UtfAnyString("");
private static final int NULL_HASHCODE = reduceHashCode(5_381, 5_381); public static final UtfAnyString NULL = new UtfAnyString();
private CharSequence buffer; private static final int NULL_HASHCODE = reduceHashCode(5_381, 5_381);
public UtfAnyString(final String string) { private CharSequence buffer;
this.buffer = string;
}
public UtfAnyString(final Utf8String utf8String) { public UtfAnyString(final String value) {
this.buffer = utf8String; this.buffer = value;
} }
private UtfAnyString(final CharSequence sequence) { public UtfAnyString(final Utf8String value) {
this.buffer = sequence; this.buffer = value;
} }
/** private UtfAnyString() {
* {@code true} if the {@link UtfAnyString} is empty }
*/
public boolean isEmpty() {
return this.buffer != null && this.buffer.length() == 0;
}
/** private UtfAnyString(final CharSequence sequence) {
* {@code true} if the {@link UtfAnyString} is {@code null} this.buffer = sequence;
*/ }
public boolean isNull() {
return null == this.buffer;
}
public boolean isUtf16() { /**
return this.buffer instanceof String; * {@code true} if the {@link UtfAnyString} is empty
} */
public boolean isEmpty() {
return this.buffer != null && this.buffer.length() == 0;
}
public boolean isUtf8() { /**
return this.buffer instanceof Utf8String; * {@code true} if the {@link UtfAnyString} is {@code null}
} */
public boolean isNull() {
return null == this.buffer;
}
/** public boolean isUtf16() {
* Returns the {@code char} value at the specified {@code index} return this.buffer instanceof String;
* <p> }
* An index ranges from zero to {@link UtfAnyString#length()} minus one. The first {@code char} value of the
* sequence is at index zero, the next at index one, and so on, as for array indexing. If the {@code char}
* value specified by the {@code index} is a surrogate, the surrogate (not the surrogate pair) is returned.
*
* @param index the index of the {@code char} value to be returned
* @return the specified {@code char} value
* @throws IndexOutOfBoundsException if the {@code index} argument is negative or not less than
* {@link UtfAnyString#length()}
* @throws UnsupportedOperationException if this {@link UtfAnyString} is {@code null}.
*/
@Override
public char charAt(final int index) {
if (this.buffer == null) {
throw new UnsupportedOperationException("String is null");
}
return this.buffer.charAt(index);
}
public int compareTo(@Nonnull final String other) { public boolean isUtf8() {
return this.buffer instanceof Utf8String;
}
checkNotNull(other); /**
* Returns the {@code char} value at the specified {@code index}
* <p>
* An index ranges from zero to {@link UtfAnyString#length()} minus one. The first {@code char} value of the
* sequence is at index zero, the next at index one, and so on, as for array indexing. If the {@code char}
* value specified by the {@code index} is a surrogate, the surrogate (not the surrogate pair) is returned.
*
* @param index the index of the {@code char} value to be returned.
* @return the specified {@code char} value
* @throws IndexOutOfBoundsException if the {@code index} argument is negative or not less than
* {@link UtfAnyString#length()}
* @throws UnsupportedOperationException if this {@link UtfAnyString} is {@code null}.
*/
@Override
public char charAt(final int index) {
if (this.buffer == null) {
throw new UnsupportedOperationException("String is null");
}
return this.buffer.charAt(index);
}
if (other == this.buffer) { public int compareTo(@Nonnull final String other) {
return 0;
}
if (this.buffer == null) { checkNotNull(other, "expected non-null other");
return -1;
}
return this.buffer instanceof String if (other == this.buffer) {
? ((String) this.buffer).compareTo(other) return 0;
: ((Utf8String) this.buffer).compareTo(other); }
}
public int compareTo(@Nonnull final Utf8String other) { if (this.buffer == null) {
return -1;
}
checkNotNull(other); return this.buffer instanceof String
? ((String) this.buffer).compareTo(other)
: ((Utf8String) this.buffer).compareTo(other);
}
if (other == this.buffer) { public int compareTo(@Nonnull final Utf8String other) {
return 0;
}
if (this.buffer == null) { checkNotNull(other, "expected non-null other");
return -1;
}
return this.buffer instanceof String if (other == this.buffer) {
? -other.compareTo((String) this.buffer) return 0;
: ((Utf8String) this.buffer).compareTo(other); }
}
@Override if (this.buffer == null) {
public int compareTo(@Nonnull final UtfAnyString other) { return -1;
}
checkNotNull(other); return this.buffer instanceof String
? -other.compareTo((String) this.buffer)
: ((Utf8String) this.buffer).compareTo(other);
}
if (other.buffer == this.buffer) { @Override
return 0; public int compareTo(@Nonnull final UtfAnyString other) {
}
if (other.buffer == null) { checkNotNull(other, "expected non-null other");
return 1;
}
if (this.buffer == null) { if (other.buffer == this.buffer) {
return -1; return 0;
} }
if (this.buffer instanceof String) { if (other.buffer == null) {
return other.buffer instanceof String return 1;
? ((String) this.buffer).compareTo((String) other.buffer) }
: -((Utf8String) other.buffer).compareTo((String) this.buffer);
}
return ((Utf8String) this.buffer).compareTo((Utf8String) other.buffer); if (this.buffer == null) {
} return -1;
}
public static UtfAnyString empty() { if (this.buffer instanceof String) {
return EMPTY; return other.buffer instanceof String
} ? ((String) this.buffer).compareTo((String) other.buffer)
: -((Utf8String) other.buffer).compareTo((String) this.buffer);
}
@Override return ((Utf8String) this.buffer).compareTo((Utf8String) other.buffer);
public boolean equals(final Object other) { }
if (other == null) { public static UtfAnyString empty() {
return false; return EMPTY;
} }
if (other instanceof String) { @Override
return this.equals((String) other); public boolean equals(final Object other) {
}
if (other instanceof Utf8String) { if (other == null) {
return this.equals((Utf8String) other); return false;
} }
if (other instanceof UtfAnyString) { if (other instanceof String) {
return this.equals((UtfAnyString) other); return this.equals((String) other);
} }
return false; if (other instanceof Utf8String) {
} return this.equals((Utf8String) other);
}
public boolean equals(final String other) { if (other instanceof UtfAnyString) {
return this.equals((UtfAnyString) other);
}
if (null == this.buffer) { return false;
return null == other; }
}
if (this.buffer instanceof String) { public boolean equals(final String other) {
return other.contentEquals(this.buffer); // skips the type check that String.equals performs
}
return ((Utf8String) this.buffer).equals(other); if (null == this.buffer) {
} return null == other;
}
public boolean equals(final Utf8String other) { if (this.buffer instanceof String) {
return other.contentEquals(this.buffer); // skips the type check that String.equals performs
}
if (null == other) { return ((Utf8String) this.buffer).equals(other);
return null == this.buffer; }
}
return other.equals(this.buffer); public boolean equals(final Utf8String other) {
}
public boolean equals(final UtfAnyString other) { if (null == other) {
return null == this.buffer;
}
if (null == other) { return other.equals(this.buffer);
return false; }
}
if (null == this.buffer) { public boolean equals(final UtfAnyString other) {
return null == other.buffer;
}
return this.buffer instanceof String ? other.buffer.equals(this.buffer) : this.buffer.equals(other.buffer); if (null == other) {
} return false;
}
@Override if (null == this.buffer) {
public int hashCode() { return null == other.buffer;
}
final long[] hash = { 5_381, 5_381 }; return this.buffer instanceof String ? other.buffer.equals(this.buffer) : this.buffer.equals(other.buffer);
}
if (this.buffer == null) { @Override
return NULL_HASHCODE; public int hashCode() {
}
if (this.buffer instanceof String) { final long[] hash = { 5_381, 5_381 };
final int ignored = ((String) this.buffer).codePoints().reduce(0, (index, codePoint) -> { if (this.buffer == null) {
if (index % 2 == 0) { return NULL_HASHCODE;
hash[0] = ((hash[0] << 5) + hash[0]) ^ codePoint; }
} else {
hash[1] = ((hash[1] << 5) + hash[1]) ^ codePoint;
}
return index;
});
return reduceHashCode(hash[0], hash[1]); if (this.buffer instanceof String) {
}
return this.buffer.hashCode(); final int ignored = ((String) this.buffer).codePoints().reduce(0, (index, codePoint) -> {
} if (index % 2 == 0) {
hash[0] = ((hash[0] << 5) + hash[0]) ^ codePoint;
} else {
hash[1] = ((hash[1] << 5) + hash[1]) ^ codePoint;
}
return index;
});
/** return reduceHashCode(hash[0], hash[1]);
* Returns the length of this character sequence. The length is the number }
* of 16-bit {@code char}s in the sequence.
*
* @return the number of {@code char}s in this sequence
*
* @throws UnsupportedOperationException if this {@link UtfAnyString} is {@code null}
*/
@Override
public int length() {
if (this.buffer == null) {
throw new UnsupportedOperationException("String is null");
}
return this.buffer.length();
}
/** return this.buffer.hashCode();
* Returns a {@code CharSequence} that is a subsequence of this sequence }
* <p>
* The subsequence starts with the {@code char} value at the specified index and ends with the{@code char} value at
* index {@code end - 1}. The length (in {@code char}s) of the returned sequence is {@code end - start}, so if
* {@code start == end}, an empty sequence is returned.
*
* @param start the start index, inclusive
* @param end the end index, exclusive
* @return the specified subsequence
* @throws IndexOutOfBoundsException if {@code start} or {@code end} are negative, {@code end} is greater than
* {@link UtfAnyString#length()}, or {@code start} is greater than {@code
* end}.
* @throws UnsupportedOperationException if string is {@code null}
*/
@Override
@Nonnull
public CharSequence subSequence(final int start, final int end) {
if (this.buffer == null) {
throw new UnsupportedOperationException("String is null");
}
return this.buffer.subSequence(start, end);
}
@Override /**
@Nonnull * Returns the length of this character sequence. The length is the number
public String toString() { * of 16-bit {@code char}s in the sequence.
return String.valueOf(this.buffer); *
} * @return the number of {@code char}s in this sequence
* @throws UnsupportedOperationException if this {@link UtfAnyString} is {@code null}
*/
@Override
public int length() {
if (this.buffer == null) {
throw new UnsupportedOperationException("String is null");
}
return this.buffer.length();
}
public String toUtf16() { /**
if (null == this.buffer) { * Returns a {@code CharSequence} that is a subsequence of this sequence
return null; * <p>
} * The subsequence starts with the {@code char} value at the specified index and ends with the{@code char} value at
return this.buffer instanceof String ? (String) this.buffer : this.buffer.toString(); * index {@code end - 1}. The length (in {@code char}s) of the returned sequence is {@code end - start}, so if
} * {@code start == end}, an empty sequence is returned.
*
* @param start the start index, inclusive
* @param end the end index, exclusive
* @return the specified subsequence
* @throws IndexOutOfBoundsException if {@code start} or {@code end} are negative, {@code end} is greater than
* {@link UtfAnyString#length()}, or {@code start} is greater than {@code
* end}.
* @throws UnsupportedOperationException if string is {@code null}
*/
@Override
@Nonnull
public CharSequence subSequence(final int start, final int end) {
if (this.buffer == null) {
throw new UnsupportedOperationException("String is null");
}
return this.buffer.subSequence(start, end);
}
public Utf8String toUtf8() { @Override
if (null == this.buffer) { @Nonnull
return null; public String toString() {
} return String.valueOf(this.buffer);
return this.buffer instanceof String ? transcodeUtf16((String) this.buffer) : (Utf8String) this.buffer; }
}
private static int reduceHashCode(final long h1, final long h2) { public String toUtf16() {
return Long.valueOf(h1 + (h2 * 1_566_083_941L)).intValue(); if (null == this.buffer) {
} return null;
}
return this.buffer instanceof String ? (String) this.buffer : this.buffer.toString();
}
public Utf8String toUtf8() {
if (null == this.buffer) {
return null;
}
return this.buffer instanceof String ? transcodeUtf16((String) this.buffer) : (Utf8String) this.buffer;
}
private static int reduceHashCode(final long h1, final long h2) {
return Long.valueOf(h1 + (h2 * 1_566_083_941L)).intValue();
}
} }

View File

@@ -16,7 +16,7 @@ import javax.annotation.Nonnull;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
public final class LayoutBinary extends LayoutTypePrimitive<byte[]> { public final class LayoutBinary extends LayoutTypePrimitive<ByteBuf> {
// implements // implements
// LayoutListWritable<Byte>, // LayoutListWritable<Byte>,
// LayoutListReadable<Byte>, // LayoutListReadable<Byte>,
@@ -41,7 +41,7 @@ public final class LayoutBinary extends LayoutTypePrimitive<byte[]> {
@Nonnull final RowBuffer buffer, @Nonnull final RowBuffer buffer,
@Nonnull final RowCursor scope, @Nonnull final RowCursor scope,
@Nonnull final LayoutColumn column, @Nonnull final LayoutColumn column,
@Nonnull final Out<byte[]> value) { @Nonnull final Out<ByteBuf> value) {
checkNotNull(buffer, "expected non-null buffer"); checkNotNull(buffer, "expected non-null buffer");
checkNotNull(scope, "expected non-null scope"); checkNotNull(scope, "expected non-null scope");
@@ -56,14 +56,14 @@ public final class LayoutBinary extends LayoutTypePrimitive<byte[]> {
return Result.NOT_FOUND; return Result.NOT_FOUND;
} }
value.set(ByteBufUtil.getBytes(buffer.readFixedBinary(scope.start() + column.offset(), column.size()))); value.set(buffer.readFixedBinary(scope.start() + column.offset(), column.size()));
return Result.SUCCESS; return Result.SUCCESS;
} }
@Override @Override
@Nonnull @Nonnull
public Result readSparse( public Result readSparse(
@Nonnull final RowBuffer buffer, @Nonnull final RowCursor edit, @Nonnull final Out<byte[]> value) { @Nonnull final RowBuffer buffer, @Nonnull final RowCursor edit, @Nonnull final Out<ByteBuf> value) {
checkNotNull(buffer, "expected non-null buffer"); checkNotNull(buffer, "expected non-null buffer");
checkNotNull(edit, "expected non-null edit"); checkNotNull(edit, "expected non-null edit");
@@ -76,7 +76,7 @@ public final class LayoutBinary extends LayoutTypePrimitive<byte[]> {
return result; return result;
} }
value.set(ByteBufUtil.getBytes(buffer.readSparseBinary(edit))); value.set(buffer.readSparseBinary(edit));
return Result.SUCCESS; return Result.SUCCESS;
} }
@@ -86,7 +86,7 @@ public final class LayoutBinary extends LayoutTypePrimitive<byte[]> {
@Nonnull RowBuffer buffer, @Nonnull RowBuffer buffer,
@Nonnull RowCursor scope, @Nonnull RowCursor scope,
@Nonnull LayoutColumn column, @Nonnull LayoutColumn column,
@Nonnull Out<byte[]> value) { @Nonnull Out<ByteBuf> value) {
checkNotNull(buffer, "expected non-null buffer"); checkNotNull(buffer, "expected non-null buffer");
checkNotNull(scope, "expected non-null scope"); checkNotNull(scope, "expected non-null scope");
@@ -101,7 +101,7 @@ public final class LayoutBinary extends LayoutTypePrimitive<byte[]> {
} }
final int valueOffset = buffer.computeVariableValueOffset(scope.layout(), scope.start(), column.offset()); final int valueOffset = buffer.computeVariableValueOffset(scope.layout(), scope.start(), column.offset());
value.set(ByteBufUtil.getBytes(buffer.readVariableBinary(valueOffset))); value.set(buffer.readVariableBinary(valueOffset));
return Result.SUCCESS; return Result.SUCCESS;
} }
@@ -112,7 +112,7 @@ public final class LayoutBinary extends LayoutTypePrimitive<byte[]> {
@Nonnull RowBuffer buffer, @Nonnull RowBuffer buffer,
@Nonnull RowCursor scope, @Nonnull RowCursor scope,
@Nonnull LayoutColumn column, @Nonnull LayoutColumn column,
@Nonnull byte[] value) { @Nonnull ByteBuf value) {
checkNotNull(buffer, "expected non-null buffer"); checkNotNull(buffer, "expected non-null buffer");
checkNotNull(scope, "expected non-null scope"); checkNotNull(scope, "expected non-null scope");
@@ -121,23 +121,21 @@ public final class LayoutBinary extends LayoutTypePrimitive<byte[]> {
checkArgument(scope.scopeType() instanceof LayoutUDT); checkArgument(scope.scopeType() instanceof LayoutUDT);
checkArgument(column.size() >= 0); checkArgument(column.size() >= 0);
checkArgument(value.length == column.size());
if (scope.immutable()) { if (scope.immutable()) {
return Result.INSUFFICIENT_PERMISSIONS; return Result.INSUFFICIENT_PERMISSIONS;
} }
final ByteBuf valueBuffer = Unpooled.wrappedBuffer(value).asReadOnly();
final int valueOffset = scope.start() + column.offset(); final int valueOffset = scope.start() + column.offset();
buffer.setBit(scope.start(), column.nullBit()); buffer.setBit(scope.start(), column.nullBit());
buffer.writeFixedBinary(valueOffset, valueBuffer, column.size()); buffer.writeFixedBinary(valueOffset, value, column.size());
return Result.SUCCESS; return Result.SUCCESS;
} }
@Override @Override
@Nonnull @Nonnull
public Result writeSparse(@Nonnull RowBuffer buffer, @Nonnull RowCursor edit, @Nonnull byte[] value) { public Result writeSparse(@Nonnull RowBuffer buffer, @Nonnull RowCursor edit, @Nonnull ByteBuf value) {
return this.writeSparse(buffer, edit, value, UpdateOptions.UPSERT); return this.writeSparse(buffer, edit, value, UpdateOptions.UPSERT);
} }
@@ -146,16 +144,21 @@ public final class LayoutBinary extends LayoutTypePrimitive<byte[]> {
public Result writeSparse( public Result writeSparse(
@Nonnull RowBuffer buffer, @Nonnull RowBuffer buffer,
@Nonnull RowCursor edit, @Nonnull RowCursor edit,
@Nonnull byte[] value, @Nonnull ByteBuf value,
@Nonnull UpdateOptions options) { @Nonnull UpdateOptions options) {
checkNotNull(buffer, "expected non-null buffer");
checkNotNull(edit, "expected non-null edit");
checkNotNull(value, "expected non-null value");
checkNotNull(options, "expected non-null options");
Result result = LayoutType.prepareSparseWrite(buffer, edit, this.typeArg(), options); Result result = LayoutType.prepareSparseWrite(buffer, edit, this.typeArg(), options);
if (result != Result.SUCCESS) { if (result != Result.SUCCESS) {
return result; return result;
} }
buffer.writeSparseBinary(edit, Unpooled.wrappedBuffer(value).asReadOnly(), options); buffer.writeSparseBinary(edit, value, options);
return Result.SUCCESS; return Result.SUCCESS;
} }
@@ -165,7 +168,12 @@ public final class LayoutBinary extends LayoutTypePrimitive<byte[]> {
@Nonnull RowBuffer buffer, @Nonnull RowBuffer buffer,
@Nonnull RowCursor scope, @Nonnull RowCursor scope,
@Nonnull LayoutColumn column, @Nonnull LayoutColumn column,
@Nonnull byte[] value) { @Nonnull ByteBuf value) {
checkNotNull(buffer, "expected non-null buffer");
checkNotNull(scope, "expected non-null scope");
checkNotNull(column, "expected non-null column");
checkNotNull(value, "expected non-null value");
checkArgument(scope.scopeType() instanceof LayoutUDT); checkArgument(scope.scopeType() instanceof LayoutUDT);
@@ -173,16 +181,15 @@ public final class LayoutBinary extends LayoutTypePrimitive<byte[]> {
return Result.INSUFFICIENT_PERMISSIONS; return Result.INSUFFICIENT_PERMISSIONS;
} }
if ((column.size() > 0) && (value.length > column.size())) { if ((column.size() > 0) && (value.readableBytes() > column.size())) {
return Result.TOO_BIG; return Result.TOO_BIG;
} }
final boolean exists = buffer.readBit(scope.start(), column.nullBit()); final boolean exists = buffer.readBit(scope.start(), column.nullBit());
final ByteBuf valueBuffer = Unpooled.wrappedBuffer(value).asReadOnly();
final int valueOffset = buffer.computeVariableValueOffset(scope.layout(), scope.start(), column.offset()); final int valueOffset = buffer.computeVariableValueOffset(scope.layout(), scope.start(), column.offset());
final Out<Integer> shift = new Out<>(); final Out<Integer> shift = new Out<>();
buffer.writeVariableBinary(valueOffset, valueBuffer, exists, shift); buffer.writeVariableBinary(valueOffset, value, exists, shift);
buffer.setBit(scope.start(), column.nullBit()); buffer.setBit(scope.start(), column.nullBit());
scope.metaOffset(scope.metaOffset() + shift.get()); scope.metaOffset(scope.metaOffset() + shift.get());
scope.valueOffset(scope.valueOffset() + shift.get()); scope.valueOffset(scope.valueOffset() + shift.get());

View File

@@ -50,7 +50,7 @@ public final class LayoutTypedTuple extends LayoutIndexedScope {
@Nonnull final RowBuffer buffer, final int offset, @Nonnull final Out<Integer> lengthInBytes) { @Nonnull final RowBuffer buffer, final int offset, @Nonnull final Out<Integer> lengthInBytes) {
checkNotNull(buffer, "expected non-null buffer"); checkNotNull(buffer, "expected non-null buffer");
lengthInBytes checkNotNull(lengthInBytes, "expected non-null lengthInBytes");
checkArgument(offset >= 0, "expected non-negative offset, not %s", offset); checkArgument(offset >= 0, "expected non-negative offset, not %s", offset);
final int numTypeArgs = (int) buffer.readVariableUInt(offset, lengthInBytes); final int numTypeArgs = (int) buffer.readVariableUInt(offset, lengthInBytes);

View File

@@ -15,7 +15,7 @@ import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
public abstract class LayoutUniqueScope extends LayoutIndexedScope { public abstract class LayoutUniqueScope extends LayoutIndexedScope implements ILayoutType {
protected LayoutUniqueScope(LayoutCode code, boolean immutable, boolean isSizedScope, boolean isTypedScope) { protected LayoutUniqueScope(LayoutCode code, boolean immutable, boolean isSizedScope, boolean isTypedScope) {
super(code, immutable, isSizedScope, false, true, isTypedScope); super(code, immutable, isSizedScope, false, true, isTypedScope);

View File

@@ -14,7 +14,8 @@ import javax.annotation.Nonnull;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
public final class LayoutUtf8 extends LayoutTypePrimitive<String> implements LayoutUtf8Readable, LayoutUtf8Writable { public final class LayoutUtf8 extends LayoutTypePrimitive<String>
implements LayoutUtf8Readable, LayoutUtf8Writable {
public LayoutUtf8() { public LayoutUtf8() {
super(LayoutCode.UTF_8, 0); super(LayoutCode.UTF_8, 0);

View File

@@ -15,199 +15,199 @@ import static com.google.common.base.Strings.lenientFormat;
public final class SchemaHash { public final class SchemaHash {
/** /**
* Computes the logical hash for a logical schema. * Computes the logical hash for a logical schema.
* *
* @param namespace The namespace within which <paramref name="schema" /> is defined. * @param namespace The namespace within which <paramref name="schema" /> is defined.
* @param schema The logical schema to compute the hash of. * @param schema The logical schema to compute the hash of.
* @param seed The seed to initialized the hash function. * @param seed The seed to initialized the hash function.
* @return The logical 128-bit hash as a two-tuple (low, high). * @return The logical 128-bit hash as a two-tuple (low, high).
*/ */
public static HashCode128 computeHash(Namespace namespace, Schema schema, HashCode128 seed) { public static HashCode128 computeHash(Namespace namespace, Schema schema, HashCode128 seed) {
HashCode128 hash = seed; HashCode128 hash = seed;
hash = Murmur3Hash.Hash128(schema.schemaId().value(), hash); hash = Murmur3Hash.Hash128(schema.schemaId().value(), hash);
hash = Murmur3Hash.Hash128(schema.type().value(), hash); hash = Murmur3Hash.Hash128(schema.type().value(), hash);
hash = SchemaHash.computeHash(namespace, schema.options(), hash); hash = SchemaHash.computeHash(namespace, schema.options(), hash);
if (schema.partitionKeys() != null) { if (schema.partitionKeys() != null) {
for (PartitionKey partitionKey : schema.partitionKeys()) { for (PartitionKey partitionKey : schema.partitionKeys()) {
hash = SchemaHash.computeHash(namespace, partitionKey, hash); hash = SchemaHash.computeHash(namespace, partitionKey, hash);
} }
} }
if (schema.primarySortKeys() != null) { if (schema.primarySortKeys() != null) {
for (PrimarySortKey p : schema.primarySortKeys()) { for (PrimarySortKey p : schema.primarySortKeys()) {
hash = SchemaHash.computeHash(namespace, p, hash); hash = SchemaHash.computeHash(namespace, p, hash);
} }
} }
if (schema.staticKeys() != null) { if (schema.staticKeys() != null) {
for (StaticKey p : schema.staticKeys()) { for (StaticKey p : schema.staticKeys()) {
hash = SchemaHash.computeHash(namespace, p, hash); hash = SchemaHash.computeHash(namespace, p, hash);
} }
} }
if (schema.properties() != null) { if (schema.properties() != null) {
for (Property p : schema.properties()) { for (Property p : schema.properties()) {
hash = SchemaHash.computeHash(namespace, p, hash); hash = SchemaHash.computeHash(namespace, p, hash);
} }
} }
return hash; return hash;
} }
private static HashCode128 computeHash(Namespace namespace, SchemaOptions options, HashCode128 seed) { private static HashCode128 computeHash(Namespace namespace, SchemaOptions options, HashCode128 seed) {
HashCode128 hash = seed; HashCode128 hash = seed;
hash = Murmur3Hash.Hash128(options != null && options.disallowUnschematized(), hash); hash = Murmur3Hash.Hash128(options != null && options.disallowUnschematized(), hash);
hash = Murmur3Hash.Hash128(options != null && options.enablePropertyLevelTimestamp(), hash); hash = Murmur3Hash.Hash128(options != null && options.enablePropertyLevelTimestamp(), hash);
hash = Murmur3Hash.Hash128(options != null && options.disableSystemPrefix(), hash); hash = Murmur3Hash.Hash128(options != null && options.disableSystemPrefix(), hash);
return hash; return hash;
} }
private static HashCode128 computeHash(Namespace ns, Property p, HashCode128 seed) { private static HashCode128 computeHash(Namespace ns, Property p, HashCode128 seed) {
HashCode128 hash = seed; HashCode128 hash = seed;
hash = Murmur3Hash.Hash128(p.path(), hash); hash = Murmur3Hash.Hash128(p.path(), hash);
hash = SchemaHash.computeHash(ns, p.propertyType(), hash); hash = SchemaHash.computeHash(ns, p.propertyType(), hash);
return hash; return hash;
} }
private static HashCode128 computeHash(Namespace namespace, PropertyType p, HashCode128 seed) { private static HashCode128 computeHash(Namespace namespace, PropertyType p, HashCode128 seed) {
HashCode128 hash = seed; HashCode128 hash = seed;
hash = Murmur3Hash.Hash128(p.type().value(), hash); hash = Murmur3Hash.Hash128(p.type().value(), hash);
hash = Murmur3Hash.Hash128(p.nullable(), hash); hash = Murmur3Hash.Hash128(p.nullable(), hash);
if (p.apiType() != null) { if (p.apiType() != null) {
hash = Murmur3Hash.Hash128(p.apiType(), hash); hash = Murmur3Hash.Hash128(p.apiType(), hash);
} }
if (p instanceof PrimitivePropertyType) { if (p instanceof PrimitivePropertyType) {
PrimitivePropertyType pp = (PrimitivePropertyType) p; PrimitivePropertyType pp = (PrimitivePropertyType) p;
hash = Murmur3Hash.Hash128(pp.storage().value(), hash); hash = Murmur3Hash.Hash128(pp.storage().value(), hash);
hash = Murmur3Hash.Hash128(pp.length(), hash); hash = Murmur3Hash.Hash128(pp.length(), hash);
return hash; return hash;
} }
checkState(p instanceof ScopePropertyType); checkState(p instanceof ScopePropertyType);
ScopePropertyType pp = (ScopePropertyType) p; ScopePropertyType pp = (ScopePropertyType) p;
hash = Murmur3Hash.Hash128(pp.immutable(), hash); hash = Murmur3Hash.Hash128(pp.immutable(), hash);
if (p instanceof ArrayPropertyType) { if (p instanceof ArrayPropertyType) {
ArrayPropertyType spp = (ArrayPropertyType) p; ArrayPropertyType spp = (ArrayPropertyType) p;
if (spp.items() != null) { if (spp.items() != null) {
hash = SchemaHash.computeHash(namespace, spp.items(), hash); hash = SchemaHash.computeHash(namespace, spp.items(), hash);
} }
return hash; return hash;
} }
if (p instanceof ObjectPropertyType) { if (p instanceof ObjectPropertyType) {
ObjectPropertyType spp = (ObjectPropertyType) p; ObjectPropertyType spp = (ObjectPropertyType) p;
if (spp.properties() != null) { if (spp.properties() != null) {
for (Property opp : spp.properties()) { for (Property opp : spp.properties()) {
hash = SchemaHash.computeHash(namespace, opp, hash); hash = SchemaHash.computeHash(namespace, opp, hash);
} }
} }
return hash; return hash;
} }
if (p instanceof MapPropertyType) { if (p instanceof MapPropertyType) {
MapPropertyType spp = (MapPropertyType) p; MapPropertyType spp = (MapPropertyType) p;
if (spp.keys() != null) { if (spp.keys() != null) {
hash = SchemaHash.computeHash(namespace, spp.keys(), hash); hash = SchemaHash.computeHash(namespace, spp.keys(), hash);
} }
if (spp.values() != null) { if (spp.values() != null) {
hash = SchemaHash.computeHash(namespace, spp.values(), hash); hash = SchemaHash.computeHash(namespace, spp.values(), hash);
} }
return hash; return hash;
} }
if (p instanceof SetPropertyType) { if (p instanceof SetPropertyType) {
SetPropertyType spp = (SetPropertyType) p; SetPropertyType spp = (SetPropertyType) p;
if (spp.items() != null) { if (spp.items() != null) {
hash = SchemaHash.computeHash(namespace, spp.items(), hash); hash = SchemaHash.computeHash(namespace, spp.items(), hash);
} }
return hash; return hash;
} }
if (p instanceof TaggedPropertyType) { if (p instanceof TaggedPropertyType) {
TaggedPropertyType spp = (TaggedPropertyType) p; TaggedPropertyType spp = (TaggedPropertyType) p;
if (spp.items() != null) { if (spp.items() != null) {
for (PropertyType pt : spp.items()) { for (PropertyType pt : spp.items()) {
hash = SchemaHash.computeHash(namespace, pt, hash); hash = SchemaHash.computeHash(namespace, pt, hash);
} }
} }
return hash; return hash;
} }
if (p instanceof TuplePropertyType) { if (p instanceof TuplePropertyType) {
TuplePropertyType spp = (TuplePropertyType) p; TuplePropertyType spp = (TuplePropertyType) p;
if (spp.items() != null) { if (spp.items() != null) {
for (PropertyType pt : spp.items()) { for (PropertyType pt : spp.items()) {
hash = SchemaHash.computeHash(namespace, pt, hash); hash = SchemaHash.computeHash(namespace, pt, hash);
} }
} }
return hash; return hash;
} }
if (p instanceof UdtPropertyType) { if (p instanceof UdtPropertyType) {
Stream<Schema> schemaStream = namespace.schemas().stream(); Stream<Schema> schemaStream = namespace.schemas().stream();
UdtPropertyType spp = (UdtPropertyType) p; UdtPropertyType spp = (UdtPropertyType) p;
Optional<Schema> udtSchema; Optional<Schema> udtSchema;
if (spp.schemaId() == SchemaId.INVALID) { if (spp.schemaId() == SchemaId.INVALID) {
udtSchema = schemaStream.filter(schema -> schema.name().equals(spp.name())).findFirst(); udtSchema = schemaStream.filter(schema -> schema.name().equals(spp.name())).findFirst();
} else { } else {
udtSchema = schemaStream.filter(schema -> schema.schemaId().equals(spp.schemaId())).findFirst(); udtSchema = schemaStream.filter(schema -> schema.schemaId().equals(spp.schemaId())).findFirst();
udtSchema.ifPresent(schema -> checkState(schema.name().equals(spp.name()), udtSchema.ifPresent(schema -> checkState(schema.name().equals(spp.name()),
"Ambiguous schema reference: '%s:%s'", spp.name(), spp.schemaId())); "Ambiguous schema reference: '%s:%s'", spp.name(), spp.schemaId()));
} }
checkState(udtSchema.isPresent(), "Cannot resolve schema reference '{0}:{1}'", spp.name(), spp.schemaId()); checkState(udtSchema.isPresent(), "Cannot resolve schema reference '{0}:{1}'", spp.name(), spp.schemaId());
return SchemaHash.computeHash(namespace, udtSchema.get(), hash); return SchemaHash.computeHash(namespace, udtSchema.get(), hash);
} }
throw new IllegalStateException(lenientFormat("unrecognized property type: %s", p.getClass())); throw new IllegalStateException(lenientFormat("unrecognized property type: %s", p.getClass()));
} }
private static HashCode128 computeHash(Namespace namespace, PartitionKey key, HashCode128 seed) { private static HashCode128 computeHash(Namespace namespace, PartitionKey key, HashCode128 seed) {
return key == null ? seed : Murmur3Hash.Hash128(key.path(), seed); return key == null ? seed : Murmur3Hash.Hash128(key.path(), seed);
} }
private static HashCode128 computeHash(Namespace namespace, PrimarySortKey key, HashCode128 seed) { private static HashCode128 computeHash(Namespace namespace, PrimarySortKey key, HashCode128 seed) {
HashCode128 hash = seed; HashCode128 hash = seed;
if (key != null) { if (key != null) {
hash = Murmur3Hash.Hash128(key.path(), hash); hash = Murmur3Hash.Hash128(key.path(), hash);
hash = Murmur3Hash.Hash128(key.direction().value(), hash); hash = Murmur3Hash.Hash128(key.direction().value(), hash);
} }
return hash; return hash;
} }
private static HashCode128 computeHash(Namespace ns, StaticKey key, HashCode128 seed) { private static HashCode128 computeHash(Namespace ns, StaticKey key, HashCode128 seed) {
return key == null ? seed : Murmur3Hash.Hash128(key.path(), seed); return key == null ? seed : Murmur3Hash.Hash128(key.path(), seed);
} }
} }

View File

@@ -5,7 +5,7 @@ package tangible;
public final class StringHelper { public final class StringHelper {
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'IndexOfAny' (1 parameter version). // This method replaces the .NET string method 'IndexOfAny' (1 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static int indexOfAny(String string, char[] anyOf) { public static int indexOfAny(String string, char[] anyOf) {
int lowestIndex = -1; int lowestIndex = -1;
@@ -26,7 +26,7 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'IndexOfAny' (2 parameter version). // This method replaces the .NET string method 'IndexOfAny' (2 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static int indexOfAny(String string, char[] anyOf, int startIndex) { public static int indexOfAny(String string, char[] anyOf, int startIndex) {
int indexInSubstring = indexOfAny(string.substring(startIndex), anyOf); int indexInSubstring = indexOfAny(string.substring(startIndex), anyOf);
@@ -38,7 +38,7 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'IndexOfAny' (3 parameter version). // This method replaces the .NET string method 'IndexOfAny' (3 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static int indexOfAny(String string, char[] anyOf, int startIndex, int count) { public static int indexOfAny(String string, char[] anyOf, int startIndex, int count) {
int endIndex = startIndex + count; int endIndex = startIndex + count;
@@ -51,14 +51,14 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET static string method 'IsNullOrEmpty'. // This method replaces the .NET static string method 'IsNullOrEmpty'.
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static boolean isNullOrEmpty(String string) { public static boolean isNullOrEmpty(String string) {
return string == null || string.length() == 0; return string == null || string.length() == 0;
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET static string method 'IsNullOrWhiteSpace'. // This method replaces the .NET static string method 'IsNullOrWhiteSpace'.
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static boolean isNullOrWhiteSpace(String string) { public static boolean isNullOrWhiteSpace(String string) {
if (string == null) { if (string == null) {
@@ -75,7 +75,7 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET static string method 'Join' (2 parameter version). // This method replaces the .NET static string method 'Join' (2 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String join(String separator, String[] stringArray) { public static String join(String separator, String[] stringArray) {
if (stringArray == null) { if (stringArray == null) {
@@ -86,7 +86,7 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET static string method 'Join' (4 parameter version). // This method replaces the .NET static string method 'Join' (4 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String join(String separator, String[] stringArray, int startIndex, int count) { public static String join(String separator, String[] stringArray, int startIndex, int count) {
String result = ""; String result = "";
@@ -109,7 +109,7 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'LastIndexOf' (char version). // This method replaces the .NET string method 'LastIndexOf' (char version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static int lastIndexOf(String string, char value, int startIndex, int count) { public static int lastIndexOf(String string, char value, int startIndex, int count) {
int leftMost = startIndex + 1 - count; int leftMost = startIndex + 1 - count;
@@ -124,7 +124,7 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'LastIndexOf' (string version). // This method replaces the .NET string method 'LastIndexOf' (string version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static int lastIndexOf(String string, String value, int startIndex, int count) { public static int lastIndexOf(String string, String value, int startIndex, int count) {
int leftMost = startIndex + 1 - count; int leftMost = startIndex + 1 - count;
@@ -139,7 +139,7 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'LastIndexOfAny' (1 parameter version). // This method replaces the .NET string method 'LastIndexOfAny' (1 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static int lastIndexOfAny(String string, char[] anyOf) { public static int lastIndexOfAny(String string, char[] anyOf) {
int highestIndex = -1; int highestIndex = -1;
@@ -158,7 +158,7 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'LastIndexOfAny' (2 parameter version). // This method replaces the .NET string method 'LastIndexOfAny' (2 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static int lastIndexOfAny(String string, char[] anyOf, int startIndex) { public static int lastIndexOfAny(String string, char[] anyOf, int startIndex) {
String substring = string.substring(0, startIndex + 1); String substring = string.substring(0, startIndex + 1);
@@ -171,7 +171,7 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'LastIndexOfAny' (3 parameter version). // This method replaces the .NET string method 'LastIndexOfAny' (3 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static int lastIndexOfAny(String string, char[] anyOf, int startIndex, int count) { public static int lastIndexOfAny(String string, char[] anyOf, int startIndex, int count) {
int leftMost = startIndex + 1 - count; int leftMost = startIndex + 1 - count;
@@ -186,14 +186,14 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'PadLeft' (1 parameter version). // This method replaces the .NET string method 'PadLeft' (1 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String padLeft(String string, int totalWidth) { public static String padLeft(String string, int totalWidth) {
return padLeft(string, totalWidth, ' '); return padLeft(string, totalWidth, ' ');
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'PadLeft' (2 parameter version). // This method replaces the .NET string method 'PadLeft' (2 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String padLeft(String string, int totalWidth, char paddingChar) { public static String padLeft(String string, int totalWidth, char paddingChar) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@@ -207,14 +207,14 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'PadRight' (1 parameter version). // This method replaces the .NET string method 'PadRight' (1 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String padRight(String string, int totalWidth) { public static String padRight(String string, int totalWidth) {
return padRight(string, totalWidth, ' '); return padRight(string, totalWidth, ' ');
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'PadRight' (2 parameter version). // This method replaces the .NET string method 'PadRight' (2 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String padRight(String string, int totalWidth, char paddingChar) { public static String padRight(String string, int totalWidth, char paddingChar) {
StringBuilder sb = new StringBuilder(string); StringBuilder sb = new StringBuilder(string);
@@ -227,21 +227,21 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'Remove' (1 parameter version). // This method replaces the .NET string method 'Remove' (1 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String remove(String string, int start) { public static String remove(String string, int start) {
return string.substring(0, start); return string.substring(0, start);
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'Remove' (2 parameter version). // This method replaces the .NET string method 'Remove' (2 parameter version).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String remove(String string, int start, int count) { public static String remove(String string, int start, int count) {
return string.substring(0, start) + string.substring(start + count); return string.substring(0, start) + string.substring(start + count);
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string constructor which repeats a character. // This method replaces the .NET string constructor which repeats a character.
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String repeatChar(char charToRepeat, int count) { public static String repeatChar(char charToRepeat, int count) {
String newString = ""; String newString = "";
@@ -252,9 +252,9 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method is used for string equality comparisons when the option // This method is used for string equality comparisons when the option
// 'Use helper 'stringsEqual' method to handle null strings' is selected // 'Use helper 'stringsEqual' method to handle null strings' is selected
// (The Java String 'equals' method can't be called on a null instance). // (The Java String 'equals' method can't be called on a null instance).
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static boolean stringsEqual(String s1, String s2) { public static boolean stringsEqual(String s1, String s2) {
if (s1 == null && s2 == null) { if (s1 == null && s2 == null) {
@@ -265,8 +265,8 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'Substring' when 'start' is a method // This method replaces the .NET string method 'Substring' when 'start' is a method
// call or calculated value to ensure that 'start' is obtained just once. // call or calculated value to ensure that 'start' is obtained just once.
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String substring(String string, int start, int length) { public static String substring(String string, int start, int length) {
if (length < 0) { if (length < 0) {
@@ -277,14 +277,14 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'Trim' when arguments are used. // This method replaces the .NET string method 'Trim' when arguments are used.
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String trim(String string, Character... charsToTrim) { public static String trim(String string, Character... charsToTrim) {
return trimEnd(trimStart(string, charsToTrim), charsToTrim); return trimEnd(trimStart(string, charsToTrim), charsToTrim);
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'TrimEnd'. // This method replaces the .NET string method 'TrimEnd'.
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String trimEnd(String string, Character... charsToTrim) { public static String trimEnd(String string, Character... charsToTrim) {
if (string == null || charsToTrim == null) { if (string == null || charsToTrim == null) {
@@ -316,7 +316,7 @@ public final class StringHelper {
} }
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// This method replaces the .NET string method 'TrimStart'. // This method replaces the .NET string method 'TrimStart'.
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
public static String trimStart(String string, Character... charsToTrim) { public static String trimStart(String string, Character... charsToTrim) {
if (string == null || charsToTrim == null) { if (string == null || charsToTrim == null) {

View File

@@ -80,7 +80,7 @@ public final class JsonModelRowGenerator {
new Reference<RowBuffer>(this.row); new Reference<RowBuffer>(this.row);
// TODO: C# TO JAVA CONVERTER: The following lambda contained an unresolved 'ref' keyword - these are not // TODO: C# TO JAVA CONVERTER: The following lambda contained an unresolved 'ref' keyword - these are not
// converted by C# to Java Converter: // converted by C# to Java Converter:
Result tempVar = RowWriter.WriteBuffer(tempReference_row, value, (RowWriter RowWriter writer, TypeArgument typeArg, Result tempVar = RowWriter.writeBuffer(tempReference_row, value, (RowWriter RowWriter writer, TypeArgument typeArg,
HashMap<Utf8String, Object> dict) -> HashMap<Utf8String, Object> dict) ->
{ {
for ((Utf8String propPath,Object propValue) :dict) for ((Utf8String propPath,Object propValue) :dict)
@@ -118,7 +118,7 @@ public final class JsonModelRowGenerator {
//ORIGINAL LINE: case bool x: //ORIGINAL LINE: case bool x:
case case
boolean x: boolean x:
return writer.get().WriteBoolean(path, x); return writer.get().writeBoolean(path, x);
// TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements: // TODO: C# TO JAVA CONVERTER: Java has no equivalent to C# pattern variables in 'case' statements:
//ORIGINAL LINE: case long x: //ORIGINAL LINE: case long x:
case case
@@ -155,7 +155,7 @@ public final class JsonModelRowGenerator {
case HashMap < Utf8String, Object > x: case HashMap < Utf8String, Object > x:
// TODO: C# TO JAVA CONVERTER: The following lambda contained an unresolved 'ref' keyword - these // TODO: C# TO JAVA CONVERTER: The following lambda contained an unresolved 'ref' keyword - these
// are not converted by C# to Java Converter: // are not converted by C# to Java Converter:
return writer.get().WriteScope(path, new TypeArgument(LayoutType.Object), x, return writer.get().writeScope(path, new TypeArgument(LayoutType.Object), x,
(RowWriter RowWriter writer2, TypeArgument typeArg, HashMap<Utf8String, Object> dict) -> (RowWriter RowWriter writer2, TypeArgument typeArg, HashMap<Utf8String, Object> dict) ->
{ {
for ((Utf8String propPath,Object propValue) :dict) for ((Utf8String propPath,Object propValue) :dict)
@@ -172,7 +172,7 @@ public final class JsonModelRowGenerator {
//ORIGINAL LINE: case List<object> x: //ORIGINAL LINE: case List<object> x:
case ArrayList < Object > x: case ArrayList < Object > x:
// TODO: C# TO JAVA CONVERTER: The following lambda contained an unresolved 'ref' keyword - these are not converted by C# to Java Converter: // TODO: C# TO JAVA CONVERTER: The following lambda contained an unresolved 'ref' keyword - these are not converted by C# to Java Converter:
return writer.get().WriteScope(path, new TypeArgument(LayoutType.Array), x, (RowWriter RowWriter writer2, TypeArgument typeArg, ArrayList<Object> list) -> return writer.get().writeScope(path, new TypeArgument(LayoutType.Array), x, (RowWriter RowWriter writer2, TypeArgument typeArg, ArrayList<Object> list) ->
{ {
for (Object elm : list) { for (Object elm : list) {
Reference<com.azure.data.cosmos.serialization.hybridrow.io.RowWriter> tempReference_writer2 = new Reference<com.azure.data.cosmos.serialization.hybridrow.io.RowWriter>(writer2); Reference<com.azure.data.cosmos.serialization.hybridrow.io.RowWriter> tempReference_writer2 = new Reference<com.azure.data.cosmos.serialization.hybridrow.io.RowWriter>(writer2);

View File

@@ -16,7 +16,6 @@ public final class AssertThrowsException {
if (input1 == null) { if (input1 == null) {
return "(null)"; return "(null)";
} }
return Assert.ReplaceNullChars(input1); return Assert.ReplaceNullChars(input1);
} }

View File

@@ -10,6 +10,7 @@ import com.azure.data.cosmos.serialization.hybridrow.Result;
import com.azure.data.cosmos.serialization.hybridrow.RowBuffer; import com.azure.data.cosmos.serialization.hybridrow.RowBuffer;
import com.azure.data.cosmos.serialization.hybridrow.RowCursor; import com.azure.data.cosmos.serialization.hybridrow.RowCursor;
import com.azure.data.cosmos.serialization.hybridrow.RowCursors; import com.azure.data.cosmos.serialization.hybridrow.RowCursors;
import com.azure.data.cosmos.serialization.hybridrow.unit.customerschema.Hotel;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.ArrayList; import java.util.ArrayList;
@@ -25,16 +26,18 @@ import java.util.UUID;
// are anonymous.")][DeploymentItem("TestData\\CustomerSchema.json", "TestData")] public sealed class // are anonymous.")][DeploymentItem("TestData\\CustomerSchema.json", "TestData")] public sealed class
// CustomerExampleUnitTests // CustomerExampleUnitTests
public final class CustomerExampleUnitTests { public final class CustomerExampleUnitTests {
private final Hotel hotelExample = new Hotel() {
Id ="The-Westin-St-John-Resort-Villas-1187",Name ="The Westin St. John Resort Villas",Phone ="+1 340-693-8000"
,Address =new Address
{ private final Hotel hotelExample = new Hotel() {
Id = "The-Westin-St-John-Resort-Villas-1187",
Name ="The Westin St. John Resort Villas",
Phone ="+1 340-693-8000",
Address = new Address {
Street = "300B Chocolate Hole", City = "Great Cruz Bay", State = "VI", PostalCode = new PostalCode { Street = "300B Chocolate Hole", City = "Great Cruz Bay", State = "VI", PostalCode = new PostalCode {
Zip = 00830, Plus4 = 0001 Zip = 00830, Plus4 = 0001
} }
} }
}; };
private LayoutResolver customerResolver; private LayoutResolver customerResolver;
private Namespace customerSchema; private Namespace customerSchema;
private Layout guestLayout; private Layout guestLayout;

View File

@@ -57,7 +57,7 @@ public final class RowWriterUnitTests {
new Reference<RowBuffer>(row); new Reference<RowBuffer>(row);
// TODO: C# TO JAVA CONVERTER: The following lambda contained an unresolved 'ref' keyword - these are not // TODO: C# TO JAVA CONVERTER: The following lambda contained an unresolved 'ref' keyword - these are not
// converted by C# to Java Converter: // converted by C# to Java Converter:
ResultAssert.IsSuccess(RowWriter.WriteBuffer(tempReference_row, null, (RowWriter RowWriter writer, ResultAssert.IsSuccess(RowWriter.writeBuffer(tempReference_row, null, (RowWriter RowWriter writer,
TypeArgument rootTypeArg, Object ignored) -> TypeArgument rootTypeArg, Object ignored) ->
{ {
ResultAssert.IsSuccess(writer.WriteNull("null")); ResultAssert.IsSuccess(writer.WriteNull("null"));