From ad9d9fa8c23034b302e2770dd65b35a78719f417 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Sat, 4 Feb 2023 14:43:53 -0500 Subject: [PATCH 1/4] Make Region fields private This is a follow-up to #58 and will release in 2.2. --- src/org/joni/Region.java | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/org/joni/Region.java b/src/org/joni/Region.java index 33ec8bb..8b75808 100644 --- a/src/org/joni/Region.java +++ b/src/org/joni/Region.java @@ -22,14 +22,10 @@ public final class Region { static final int REGION_NOTPOS = -1; - @Deprecated - public final int numRegs; - @Deprecated - public final int[] beg; - @Deprecated - public final int[] end; - @Deprecated - public CaptureTreeNode historyRoot; + private final int numRegs; + private final int[] beg; + private final int[] end; + private CaptureTreeNode historyRoot; @SuppressWarnings("deprecation") public static Region newRegion(int num) { @@ -42,7 +38,6 @@ public static Region newRegion(int begin, int end) { } @Deprecated - @SuppressWarnings("deprecation") public Region(int num) { this.numRegs = num; this.beg = new int[num]; @@ -50,14 +45,12 @@ public Region(int num) { } @Deprecated - @SuppressWarnings("deprecation") public Region(int begin, int end) { this.numRegs = 1; this.beg = new int[]{begin}; this.end = new int[]{end}; } - @SuppressWarnings("deprecation") public Region clone() { Region region = new Region(numRegs); System.arraycopy(beg, 0, region.beg, 0, beg.length); @@ -66,32 +59,26 @@ public Region clone() { return region; } - @SuppressWarnings("deprecation") public int getNumRegs() { return numRegs; } - @SuppressWarnings("deprecation") public int getBeg(int index) { return beg[index]; } - @SuppressWarnings("deprecation") public int setBeg(int index, int value) { return beg[index] = value; } - @SuppressWarnings("deprecation") public int getEnd(int index) { return end[index]; } - @SuppressWarnings("deprecation") public int setEnd(int index, int value) { return end[index] = value; } - @SuppressWarnings("deprecation") public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Region: \n"); @@ -99,17 +86,14 @@ public String toString() { return sb.toString(); } - @SuppressWarnings("deprecation") CaptureTreeNode getCaptureTree() { return historyRoot; } - @SuppressWarnings("deprecation") CaptureTreeNode setCaptureTree(CaptureTreeNode ctn) { return this.historyRoot = ctn; } - @SuppressWarnings("deprecation") void clear() { for (int i=0; i Date: Sat, 4 Feb 2023 16:57:48 -0500 Subject: [PATCH 2/4] Only allocate a single array for beg/end --- src/org/joni/Region.java | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/org/joni/Region.java b/src/org/joni/Region.java index 8b75808..1f3d6ef 100644 --- a/src/org/joni/Region.java +++ b/src/org/joni/Region.java @@ -19,12 +19,13 @@ */ package org.joni; +import java.util.Arrays; + public final class Region { static final int REGION_NOTPOS = -1; private final int numRegs; - private final int[] beg; - private final int[] end; + private final int[] begEnd; private CaptureTreeNode historyRoot; @SuppressWarnings("deprecation") @@ -40,21 +41,18 @@ public static Region newRegion(int begin, int end) { @Deprecated public Region(int num) { this.numRegs = num; - this.beg = new int[num]; - this.end = new int[num]; + this.begEnd = new int[num * 2]; } @Deprecated public Region(int begin, int end) { this.numRegs = 1; - this.beg = new int[]{begin}; - this.end = new int[]{end}; + this.begEnd = new int[]{begin, end}; } public Region clone() { Region region = new Region(numRegs); - System.arraycopy(beg, 0, region.beg, 0, beg.length); - System.arraycopy(end, 0, region.end, 0, end.length); + System.arraycopy(begEnd, 0, region.begEnd, 0, begEnd.length); if (historyRoot != null) region.historyRoot = historyRoot.cloneTree(); return region; } @@ -64,25 +62,25 @@ public int getNumRegs() { } public int getBeg(int index) { - return beg[index]; + return begEnd[index * 2]; } public int setBeg(int index, int value) { - return beg[index] = value; + return begEnd[index * 2] = value; } public int getEnd(int index) { - return end[index]; + return begEnd[index * 2 + 1]; } public int setEnd(int index, int value) { - return end[index] = value; + return begEnd[index * 2 + 1] = value; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Region: \n"); - for (int i=0; i Date: Sat, 4 Feb 2023 17:56:04 -0500 Subject: [PATCH 3/4] Add a lightweight region for numRegs == 1 Whie benchmarking the CSV library in JRuby, one of the largest groups of allocated objects was int[] primarily for Region objects, some of which most likely only have one regionand do not need the flexibility of an array of regions. This commit splits Region into multi and single forms, so that single-region objects can be as compact as possible and not require a second (or third) object for the beg/end arrays. --- pom.xml | 2 +- src/org/joni/MultiRegion.java | 68 ++++++++++++++++++++++++++++++++++ src/org/joni/Region.java | 60 +++++++----------------------- src/org/joni/SingleRegion.java | 68 ++++++++++++++++++++++++++++++++++ 4 files changed, 150 insertions(+), 48 deletions(-) create mode 100644 src/org/joni/MultiRegion.java create mode 100644 src/org/joni/SingleRegion.java diff --git a/pom.xml b/pom.xml index 103b0f6..6ae9a70 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jruby.joni joni jar - 2.1.49-SNAPSHOT + 2.2.0-SNAPSHOT Joni Java port of Oniguruma: http://www.geocities.jp/kosako3/oniguruma diff --git a/src/org/joni/MultiRegion.java b/src/org/joni/MultiRegion.java new file mode 100644 index 0000000..efff2eb --- /dev/null +++ b/src/org/joni/MultiRegion.java @@ -0,0 +1,68 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.joni; + +import java.util.Arrays; + +public final class MultiRegion extends Region { + private final int numRegs; + private final int[] begEnd; + + public MultiRegion(int num) { + this.numRegs = num; + this.begEnd = new int[num * 2]; + } + + public MultiRegion(int begin, int end) { + this.numRegs = 1; + this.begEnd = new int[]{begin, end}; + } + + public final int getNumRegs() { + return numRegs; + } + + public MultiRegion clone() { + MultiRegion region = new MultiRegion(numRegs); + System.arraycopy(begEnd, 0, region.begEnd, 0, begEnd.length); + if (getCaptureTree() != null) region.setCaptureTree(getCaptureTree().cloneTree()); + return region; + } + + public int getBeg(int index) { + return begEnd[index * 2]; + } + + public int setBeg(int index, int value) { + return begEnd[index * 2] = value; + } + + public int getEnd(int index) { + return begEnd[index * 2 + 1]; + } + + public int setEnd(int index, int value) { + return begEnd[index * 2 + 1] = value; + } + + void clear() { + Arrays.fill(begEnd, REGION_NOTPOS); + } +} diff --git a/src/org/joni/Region.java b/src/org/joni/Region.java index 1f3d6ef..ace0442 100644 --- a/src/org/joni/Region.java +++ b/src/org/joni/Region.java @@ -19,68 +19,36 @@ */ package org.joni; -import java.util.Arrays; - -public final class Region { +public abstract class Region { static final int REGION_NOTPOS = -1; - private final int numRegs; - private final int[] begEnd; - private CaptureTreeNode historyRoot; + protected CaptureTreeNode historyRoot; - @SuppressWarnings("deprecation") public static Region newRegion(int num) { - return new Region(num); + if (num == 1) return new SingleRegion(num); + return new MultiRegion(num); } - @SuppressWarnings("deprecation") public static Region newRegion(int begin, int end) { - return new Region(begin, end); - } - - @Deprecated - public Region(int num) { - this.numRegs = num; - this.begEnd = new int[num * 2]; + return new SingleRegion(begin, end); } - @Deprecated - public Region(int begin, int end) { - this.numRegs = 1; - this.begEnd = new int[]{begin, end}; - } - - public Region clone() { - Region region = new Region(numRegs); - System.arraycopy(begEnd, 0, region.begEnd, 0, begEnd.length); - if (historyRoot != null) region.historyRoot = historyRoot.cloneTree(); - return region; - } + public abstract Region clone(); - public int getNumRegs() { - return numRegs; - } + public abstract int getNumRegs(); - public int getBeg(int index) { - return begEnd[index * 2]; - } + public abstract int getBeg(int index); - public int setBeg(int index, int value) { - return begEnd[index * 2] = value; - } + public abstract int setBeg(int index, int value); - public int getEnd(int index) { - return begEnd[index * 2 + 1]; - } + public abstract int getEnd(int index); - public int setEnd(int index, int value) { - return begEnd[index * 2 + 1] = value; - } + public abstract int setEnd(int index, int value); public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Region: \n"); - for (int i=0; i Date: Tue, 23 May 2023 10:31:44 -0500 Subject: [PATCH 4/4] Drop numRegs field It's equivalent to begEnd.length / 2. --- src/org/joni/MultiRegion.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/org/joni/MultiRegion.java b/src/org/joni/MultiRegion.java index efff2eb..46e925b 100644 --- a/src/org/joni/MultiRegion.java +++ b/src/org/joni/MultiRegion.java @@ -22,25 +22,22 @@ import java.util.Arrays; public final class MultiRegion extends Region { - private final int numRegs; private final int[] begEnd; public MultiRegion(int num) { - this.numRegs = num; this.begEnd = new int[num * 2]; } public MultiRegion(int begin, int end) { - this.numRegs = 1; this.begEnd = new int[]{begin, end}; } public final int getNumRegs() { - return numRegs; + return begEnd.length / 2; } public MultiRegion clone() { - MultiRegion region = new MultiRegion(numRegs); + MultiRegion region = new MultiRegion(getNumRegs()); System.arraycopy(begEnd, 0, region.begEnd, 0, begEnd.length); if (getCaptureTree() != null) region.setCaptureTree(getCaptureTree().cloneTree()); return region;