Compare commits

11 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
e0a045f1e8 Merge pull request 'update dependencies' (#1) from update-dependencies into master
Reviewed-on: #1
2022-08-15 15:56:22 +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.
*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
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:
```groovy
apply plugin: 'maven'
repositories {
maven { url 'https://repo.lucares.org/' }
maven { url 'https://repo.lucares.de/' }
}
dependencies {
compile 'org.lucares:primitiveCollections:0.3'
@@ -32,21 +23,25 @@ dependencies {
# Examples
## IntList / LongList
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.
### isSorted()
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
import org.lucares.collections.IntList;
final IntList list = IntList.of(1, 3, 5);
System.out.println(list + " is sorted: " + list.isSorted());
public class Example {
public static void main(final String[] args) {
final IntList list = IntList.of(1, 3, 5);
System.out.println(list + " is sorted: " + list.isSorted());
list.insert(2, 7);
System.out.println(list + " is sorted: " + list.isSorted());
list.insert(2, 7);
System.out.println(list + " is sorted: " + list.isSorted());
list.sort();
System.out.println(list + " is sorted: " + list.isSorted());
}
}
list.sort();
System.out.println(list + " is sorted: " + list.isSorted());
```
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, 5, 7] is sorted: true
```

View File

@@ -1,4 +1,4 @@
/*
buildscript {
repositories {
maven {
@@ -7,23 +7,24 @@ buildscript {
}
dependencies {
// 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 {
// 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: 'eclipse'
ext {
javaVersion=11
version_junit = '5.9.0'
version_junit_platform = '1.9.0'
javaVersion=17
version_junit = '5.9.2'
version_junit_platform = '1.9.2'
}
@@ -38,20 +39,15 @@ subprojects {
apply plugin: 'eclipse'
//apply plugin: 'maven'
apply plugin: 'maven-publish'
apply plugin: 'me.champeau.gradle.jmh'
apply plugin: 'me.champeau.jmh'
// java compatibility version
sourceCompatibility = 11
sourceCompatibility = 17
configurations {
tests
}
// the repositories for external depenencies
repositories {
mavenCentral()
}
/**
* Publish the to a local repository.
* Use 'gradlew publishToMavenLocal' to publish to the local maven repo.
@@ -100,11 +96,12 @@ subprojects {
jmh {
//jvmArgsAppend = ""
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
}
}
wrapper {
gradleVersion = '7.5.1'
gradleVersion = '8.6'
}

Binary file not shown.

View File

@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
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
zipStorePath=wrapper/dists

35
gradlew vendored
View File

@@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (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.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +80,11 @@ do
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -133,22 +131,29 @@ location of your Java installation."
fi
else
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
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
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 ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | 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" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# 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 -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \

21
gradlew.bat vendored
View File

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