From a202c47c65d130b5f32c9ed0a5483d67eebda45b Mon Sep 17 00:00:00 2001 From: Andrea Cavalli Date: Wed, 9 Feb 2022 21:06:02 +0100 Subject: [PATCH] Optimize entities cache --- .../meta/MemoizedUTF16String.java | 38 +++++++++++++++++++ .../meta/MemoizedUTF16Substring.java | 35 +++++++++++++++++ .../meta/api/objects/MessageEntity.java | 25 +++++++----- 3 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/MemoizedUTF16String.java create mode 100644 telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/MemoizedUTF16Substring.java diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/MemoizedUTF16String.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/MemoizedUTF16String.java new file mode 100644 index 00000000..291807f5 --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/MemoizedUTF16String.java @@ -0,0 +1,38 @@ +package org.telegram.telegrambots.meta; + +import java.nio.charset.StandardCharsets; + +public class MemoizedUTF16String { + + private final String original; + + private byte[] cache; + + public MemoizedUTF16String(String string) { + this.original = string; + } + + public MemoizedUTF16String(byte[] utf16Data) { + this.original = null; + this.cache = utf16Data; + } + + public byte[] getBytes() { + if (original != null && cache == null) { + byte[] newCache = original.getBytes(StandardCharsets.UTF_16LE); + this.cache = newCache; + return newCache; + } else { + return cache; + } + } + + public String substring(int offsetUtf16, int lengthUtf16) { + byte[] bytes = getBytes(); + if (bytes != null) { + return new String(bytes, offsetUtf16, lengthUtf16, StandardCharsets.UTF_16LE); + } else { + return ""; + } + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/MemoizedUTF16Substring.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/MemoizedUTF16Substring.java new file mode 100644 index 00000000..22214f28 --- /dev/null +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/MemoizedUTF16Substring.java @@ -0,0 +1,35 @@ +package org.telegram.telegrambots.meta; + +import java.nio.charset.StandardCharsets; + +public class MemoizedUTF16Substring { + + private final MemoizedUTF16String parentString; + private final int offsetUtf16; + private final int lengthUtf16; + + private String cache; + + public MemoizedUTF16Substring(MemoizedUTF16String parentString, int offsetUtf16, int lengthUtf16) { + this.parentString = parentString; + this.offsetUtf16 = offsetUtf16; + this.lengthUtf16 = lengthUtf16; + } + + public String getString() { + if (parentString != null && cache == null) { + String newString = parentString.substring(offsetUtf16, lengthUtf16); + if (newString == null) { + this.cache = ""; + return ""; + } else { + this.cache = newString; + return newString; + } + } else if (cache != null) { + return cache; + } else { + return ""; + } + } +} diff --git a/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/api/objects/MessageEntity.java b/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/api/objects/MessageEntity.java index 362f7376..a0c16d9a 100644 --- a/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/api/objects/MessageEntity.java +++ b/telegrambots-meta/src/main/java/org/telegram/telegrambots/meta/api/objects/MessageEntity.java @@ -5,6 +5,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.function.Supplier; +import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.EqualsAndHashCode; @@ -14,6 +16,8 @@ import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.ToString; +import org.telegram.telegrambots.meta.MemoizedUTF16String; +import org.telegram.telegrambots.meta.MemoizedUTF16Substring; import org.telegram.telegrambots.meta.api.interfaces.BotApiObject; /** @@ -73,18 +77,19 @@ public class MessageEntity implements BotApiObject { private User user; ///< Optional. For “text_mention” only, the mentioned user @JsonProperty(LANGUAGE_FIELD) private String language; ///< Optional. For “pre” only, the programming language of the entity text + @Setter(AccessLevel.NONE) @JsonIgnore - private String text; ///< Text present in the entity. Computed from offset and length + private MemoizedUTF16Substring text; ///< Text present in the entity. Computed from offset and length - public void computeText(String message) { - if (message != null) { - byte[] bytes = message.getBytes(StandardCharsets.UTF_16LE); - if (bytes.length >= offset && offset >= 0 && length >= 0) { - text = new String(Arrays.copyOfRange(bytes, offset, offset + length), - StandardCharsets.UTF_16LE); - } else { - text = ""; - } + public String getText() { + if (text == null) { + return ""; + } else { + return text.getString(); } } + + public void computeText(String message) { + text = new MemoizedUTF16Substring(new MemoizedUTF16String(message), offset, length); + } }