Compare commits

...

10 Commits

Author SHA1 Message Date
d77d00cb37 remove reviewboardrc
We don't use the review board anymore.
2025-04-27 10:16:10 +02:00
9845c00a9f improve documentation 2025-04-27 10:15:35 +02:00
98a3cf9ebe update gradle to 8.6 2024-03-10 14:05:12 +01:00
e6b60ed59b update to jdk 17 2023-02-08 20:11:22 +01:00
68567c1b48 Merge branch 'master' of https://git.lucares.de/andi/primitive-collections 2023-02-08 20:04:21 +01:00
0e98ba493b update 3rd party libs 2023-02-08 19:50:53 +01:00
ee55ed9683 Update 'README.md' 2022-08-25 15:12:53 +00:00
88808edf01 Update 'README.md' 2022-08-22 18:02:18 +00:00
58891020e8 Update 'README.md' 2022-08-15 16:19:49 +00:00
078c0273bf Update 'README.md' 2022-08-15 16:18:50 +00:00
9 changed files with 128 additions and 83 deletions

View File

@@ -1,2 +0,0 @@
REVIEWBOARD_URL = 'http:///'
REPOSITORY = 'PrimitiveCollections'

View File

@@ -1,19 +1,11 @@
Java collections for primitives (currently only int) released under [MIT](https://opensource.org/licenses/MIT) license. Java collections for primitives (currently only int) released under [MIT](https://opensource.org/licenses/MIT) license.
*IntList* and *LongList* are implementations of lists that store primitive integers/longs. The ints/longs are stored in an int/long array and the class takes care of growing the array as needed. You can trim the list to reduce the memory overhead. No dependencies. *IntList* and *LongList* are implementations of lists that store primitive integers/longs. The ints/longs are stored in an int/long array and the class takes care of growing the array as needed. You can trim the list to reduce the memory overhead. The feature that separates this implementation from others is that the lists keep track of whether they are sorted. This enables powerfull optimizations for searching, union or retain operations.
The lists support the following operations: *LongLongHashMap* and *LongObjHashMap* are maps that use primitive longs as keys.
*Sparse2DLongArray* is a memory efficient alternative to *long[][]*. In contrast to *long[][]* the indices are signed longs, which allows you to have negative keys and keys > 2^31.
* add/remove elements via single and bulk operations
* replace elements
* sort and shuffle
* the lists know whether or not they are sorted and can leverage that knowledge for searching (binary search), union and intersection
* search for elements
* union, intersection, retainIf, retainAll removeIf, removeAll
* clear and trim are separate methods, so that the list can be re-used without having to re-allocate memory
* stream support
* the lists are serializable and cloneable
* the lists are **not** thread-safe
# How to use # How to use
The library is still considered beta. There no pre-build artifacts on Maven Central or JCenter, but you can download them from repo.lucares.org. The library is still considered beta. There no pre-build artifacts on Maven Central or JCenter, but you can download them from repo.lucares.org.
@@ -21,9 +13,8 @@ The library is still considered beta. There no pre-build artifacts on Maven Cent
Example for Gradle: Example for Gradle:
```groovy ```groovy
apply plugin: 'maven'
repositories { repositories {
maven { url 'https://repo.lucares.org/' } maven { url 'https://repo.lucares.de/' }
} }
dependencies { dependencies {
compile 'org.lucares:primitiveCollections:0.3' compile 'org.lucares:primitiveCollections:0.3'
@@ -32,11 +23,17 @@ dependencies {
# Examples # Examples
```java ## IntList / LongList
import org.lucares.collections.IntList; An alternative to `int[]`/`long[]` that grows dynamically. The list supports a few features that are either not supported
by arrays or that would be expensive to implement. The most unique feature is that the list knows if it is sorted.
public class Example { ### isSorted()
public static void main(final String[] args) { The lists keep track of whether they are sorted or not. This makes the call to `isSorted()` very cheap, because we only have to return the value of a field. The drawback is that some operations are much more expensive. This affects `shuffle()`,
as well as `remove(int, int)`, `removeIf()`, `removeAll(IntList)` and 'retainAll()' if the list was not sorted before.
The fact that we know if a list is sorted allows us to use more efficient algorithms for `union(IntList, IntList)`, `intersection(IntList, IntList)`, `indexOf(int)`, `lastIndexOf()` and `uniq()`.
```java
final IntList list = IntList.of(1, 3, 5); final IntList list = IntList.of(1, 3, 5);
System.out.println(list + " is sorted: " + list.isSorted()); System.out.println(list + " is sorted: " + list.isSorted());
@@ -45,8 +42,6 @@ public class Example {
list.sort(); list.sort();
System.out.println(list + " is sorted: " + list.isSorted()); System.out.println(list + " is sorted: " + list.isSorted());
}
}
``` ```
Running this program gives the following output: Running this program gives the following output:
@@ -56,3 +51,6 @@ Running this program gives the following output:
[1, 3, 7, 5] is sorted: false [1, 3, 7, 5] is sorted: false
[1, 3, 5, 7] is sorted: true [1, 3, 5, 7] is sorted: true
``` ```

View File

@@ -1,4 +1,4 @@
/*
buildscript { buildscript {
repositories { repositories {
maven { maven {
@@ -7,23 +7,24 @@ buildscript {
} }
dependencies { dependencies {
// run with Java 11 and ./gradlew --no-daemon clean jmh // run with Java 11 and ./gradlew --no-daemon clean jmh
classpath "me.champeau.gradle:jmh-gradle-plugin:0.5.3" classpath "me.champeau.gradle:jmh-gradle-plugin:0.7.2"
} }
} }
*/
plugins { plugins {
// usage: gradle dependencyUpdates -Drevision=release // usage: gradle dependencyUpdates -Drevision=release
id "com.github.ben-manes.versions" version "0.42.0" id "com.github.ben-manes.versions" version "0.45.0"
} }
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'eclipse' apply plugin: 'eclipse'
ext { ext {
javaVersion=11 javaVersion=17
version_junit = '5.9.0' version_junit = '5.9.2'
version_junit_platform = '1.9.0' version_junit_platform = '1.9.2'
} }
@@ -38,20 +39,15 @@ subprojects {
apply plugin: 'eclipse' apply plugin: 'eclipse'
//apply plugin: 'maven' //apply plugin: 'maven'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
apply plugin: 'me.champeau.gradle.jmh' apply plugin: 'me.champeau.jmh'
// java compatibility version // java compatibility version
sourceCompatibility = 11 sourceCompatibility = 17
configurations { configurations {
tests tests
} }
// the repositories for external depenencies
repositories {
mavenCentral()
}
/** /**
* Publish the to a local repository. * Publish the to a local repository.
* Use 'gradlew publishToMavenLocal' to publish to the local maven repo. * Use 'gradlew publishToMavenLocal' to publish to the local maven repo.
@@ -100,11 +96,12 @@ subprojects {
jmh { jmh {
//jvmArgsAppend = "" //jvmArgsAppend = ""
resultFormat = "JSON" resultFormat = "JSON"
include = ['.*BenchmarkMultiwayMerge.*'] // include pattern (regular expression) for benchmarks to be executed includes = ['.*BenchmarkMultiwayMerge.*'] // include pattern (regular expression) for benchmarks to be executed
//includes = ['.*']
//exclude = ['some regular expression'] // exclude pattern (regular expression) for benchmarks to be executed //exclude = ['some regular expression'] // exclude pattern (regular expression) for benchmarks to be executed
} }
} }
wrapper { wrapper {
gradleVersion = '7.5.1' gradleVersion = '8.6'
} }

Binary file not shown.

View File

@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

35
gradlew vendored
View File

@@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +80,11 @@ do
esac esac
done done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # This is normally unused
# shellcheck disable=SC2034
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@@ -133,22 +131,29 @@ location of your Java installation."
fi fi
else else
JAVACMD=java JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
case $MAX_FD in #( case $MAX_FD in #(
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
done done
fi fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
# shell script including quotes and variable substitutions, so put them in DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded. # Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \

21
gradlew.bat vendored
View File

@@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@@ -42,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail
@@ -56,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. echo location of your Java installation. 1>&2
goto fail goto fail

View File

@@ -106,6 +106,12 @@ class MultiwayLongMerger {
} }
} }
/**
* Returns the next power of two that is equal or larger than i.
* or more formally: x where x = 2^n and x >= i for n ∈ and n minimal
* @param i some positive integer
* @return smallest integer that is a power of two and equal or larger than i
*/
private static int nextPowOfTwo(int i) { private static int nextPowOfTwo(int i) {
return Integer.highestOneBit(i - 1) << 1; return Integer.highestOneBit(i - 1) << 1;
} }
@@ -164,22 +170,32 @@ class MultiwayLongMerger {
} }
/** /**
* A heap is a tree where the value of the parent is smaller than the value of its children.
* <pre> * <pre>
* 7 * 23
* 3
* 8
* 1
* 9
* 4
* 10
* 0
* 11
* 5
* 12
* 2
* 13 * 13
* 6
* 14 * 14
* 9
* 37
* 24
* 77
* 5
* 44
* 35
* 93
* 7
* 29
* 27
* 31 ┌────────────────────────┬────┐
* ┌────┼──────────────┬────┐ │ │
* ┌────┬────┐ │ │ │ │ │ │
* ┏━━┷━┳━━━━┳━━━━┳━━┷━┳━━┷━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┳━━━━┓
* ┃ 5 ┃ 9 ┃ 7 ┃ 13 ┃ 24 ┃ 35 ┃ 27 ┃ 23 ┃ 14 ┃ 37 ┃ 77 ┃ 93 ┃ 29 ┃ 31 ┃
* ┗━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┻━━━━┛
* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 (array indices)
* │ │ │ │ │ │
* └────┼────┴────┘ │ │
* └──────────────┴────┘
* </pre> * </pre>
*/ */
private void init() { private void init() {

View File

@@ -1 +1,25 @@
pluginManagement {
repositories {
maven {
url "http://localhost:8081/repository/maven-public/"
allowInsecureProtocol true
}
}
}
plugins {
id("me.champeau.jmh") version "0.7.2" apply false
}
dependencyResolutionManagement {
repositories {
maven {
url "http://localhost:8081/repository/maven-public/"
allowInsecureProtocol true
}
}
}
include "primitiveCollections" include "primitiveCollections"