Clojure's data structures modified for use outside of Clojure

Overview
This library has been extracted from the master branch of Clojure (http://clojure.org)

version 1.5.1 (as of October 2013)

http://github.com/richhickey/clojure

created by Rich Hickey. The core data structures and algorithms are due to him.
This library is distributed with the same license as the Clojure programming 
language itself (EPL, see file epl-v10.html).

It has been modified by Karl Krukow <[email protected]>, and mistakes introduced are mine.


Maven

<dependency>
  <groupId>com.github.krukow</groupId>
  <artifactId>clj-ds</artifactId>
  <version>0.0.4</version>
</dependency>


*WHY*
First, I love Clojure :) ... 
Unfortunately sometimes clients require that I use Java...

The data structures used in the Clojure programming language are a great
implementation of a number of useful persistent data structures 
(see e.g., the section on immutable data structures on
http://clojure.org/functional_programming). 

However, these data structures are tailor-made to work optimally in the
Clojure programming language, and while it is possible to use these from
Java (since Clojure is distributed as a .jar file), it is inconvenient
for a number of reasons (see below). Since it is (unfortunately) not always
possible to use Clojure, I've created this library to at least reap some of the
Clojure benefits in environments constrained to Java. 
Beyond Java, other JVM languages like Erjang, Scala, JRuby and Groovy may benefit
from immutability & persistence, and from this implementation.

*Advantages of clj-ds when constrained to working with Java*
Currently the Clojure data structures are implemented in Java. In the future,
all of Clojure will be implemented in Clojure itself (known as "Clojure-in-Clojure").
This has many advantages for Clojure, but when it happens the data structures will 
probably be even more intertwined with the rest of the language, 
and may be even more inconvenient to use in a Java context.

The clj-ds project will maintain Java versions of the code, and where possible attempt
to "port" improvements made in the Clojure versions back into clj-ds. Thus keeping maintained
versions of the Java data structures. 

In the current Clojure version, calling certain methods on PersistentHashMap requires
loading the entire Clojure runtime, including the bootstrap process. This takes about one second.
This means that the first time one of these methods is called, a Java user will experience a
slight delay (and a memory-usage increase). Further, many of the Clojure runtime 
Java classes are not needed when only support for persistent data structures 
is wanted (e.g., the compiler).

The clj-ds library is not dependent on the Clojure runtime nor does it run any
Clojure bootstrap process, e.g., the classes that deal with compilation have been removed. 
This results in a smaller library, and the mentioned delay does not occur.

Clojure is a dynamically typed language. Java is statically typed, and supports
'generics' from version 5. A Java user would expect generics support from a Java
data structure library, and the Clojure version doesn't have this. 
clj-ds will support generics.

Finally, a slight improvement. 
Certain of the Clojure data structure methods use Clojure's 'seq' abstraction
in the implementation of the Java 'iterator' pattern. It is possible, to make
slightly more efficient iterators using a tailor made iterator. clj-ds does this.

Example stats for iterating through various data structures:
(20-40% improvement, matters only for quite large structures)

PersistentHashSet:
----
500.000 elements
58 ms (Java avg.)
192 ms (Pure Clojure avg)
106 ms (clj-ds avg)
---
1 mio elements:
104 ms (Java avg.)
497 ms (Pure Clojure avg)
371 ms (clj-ds avg)

---
PersistentHashMap
---
500.000 elements
94 ms (Java avg.)
189 ms (Pure Clojure avg)
131 ms (clj-ds avg)

1 mio elements:
128 ms (Java avg.)
549 ms (Pure Clojure avg)
394 ms (clj-ds avg)

---
PersistentVector 
---
1 mio elements:
104 ms (Java avg.)
122 ms (Pure Clojure avg)
104 ms (clj-ds avg)

2 mio elements:
186 ms (Java avg.)
223 ms (Pure Clojure avg)
184 ms (clj-ds avg)
Comments
  • Newer API; less cruft

    Newer API; less cruft

    I've been working on removing a lot of the cruft from the code. Things that aren't needed like the entire huge RT class, a lot dead code in the implementation.

    While I am at it, I've been moving towards an api NOT designed by a compiler writer ;)

    Please take a look and let me know what you think!

    https://github.com/grignaak/clj-ds/tree/java-api

    opened by grignaak 4
  • Maven Central

    Maven Central

    I'd like to be able to use this library more conveniently from other libraries, but that means (in practice) putting it in maven central.

    I'd be happy to do one of the following:

    1. Convert the build to maven

    or

    1. Maintain a package in maven central (which I'll do by maintaining a mavenized version, same code, slightly diff roject layout and add a pom)
    opened by brianm 4
  • raw merge with clojure 1.5.1

    raw merge with clojure 1.5.1

    hi karl,

    i did merge clojure 1.5.1 in clj-ds. it is quite "raw". i have change the snapshot version to 0.0.2-SNAPSHOT.

    some remark:

    • they added a new iterator for PersitentVector. I have named the method iterator151() and let your own version be the used version.
    • I did not add the diverse new interfaces like IHashEq to the TRIES classes that you have written.
    • not a lot changed. some 'throws Exception' are away and some tuning was done in PersistentVector.

    what do you think?

    cheers! stan.

    opened by stanislas 3
  • IPersistent* interfaces

    IPersistent* interfaces

    Hi,

    what's the idiomatic way of creating a set of some elements, checking if the set contains something and iterating over it? I've run into a couple issues there:

    1. IPersistenSet.cons returns IPersistentCollection, and it's impossible to call contains without casting.
    2. IPersistentSet doesn't implement Iterable, explicit casting required here as well.

    Is it by design, or something to fix? The first issue would be fixed very easily, the second one is trickier as APersistentSet and APersistentTrie (both implementing IPersistentSet) would have to have different Iterable type parameters.

    opened by donnerpeter 2
  • Empty PersistentList can not be instantiated

    Empty PersistentList can not be instantiated

    I am not able to use

    PersistentList empty = PersistentList.emptyList()

    as it gives following error

    required: PersistentList found: IPersistentList where T is a type-variable: T extends Object declared in method emptyList()

    I am not able to fix this in the source. Can you please fix this?

    opened by anuj919 2
  • Strengthen types of some update methods

    Strengthen types of some update methods

    A number of the public collection modification methods were returning the type of their interface, rather than their concrete type.

    For example, PersistentTreeSet.cons returned IPersistentSet, even though it always returns a PersistentTreeSet. This property makes these data structures a lot harder to work with in Java, as users must continually cast return values of these methods.

    Attached commits strengthen the return types of such methods.

    opened by jordanlewis 1
  • Convert build to use Maven

    Convert build to use Maven

    Change converts the build to maven and adds the incantations to the pom to allow pushing snapshots and releases into the sonatype open source repo, which syncs to maven central.

    opened by brianm 1
  • Java-like hierarchy for clj-ds

    Java-like hierarchy for clj-ds

    Hi Karl,

    I had to make a bit annoying change in ITransientVector in order to create the TransientVector interface. But I think it is unavoidable.

    cheers! stan.

    opened by stanislas 0
  • Apply PersistentHashMap.transient fix from mainline

    Apply PersistentHashMap.transient fix from mainline

    Fix dissoccing colliding values in a transient hashmap (CLJ-829)

    This bug, detailed in http://dev.clojure.org/jira/browse/CLJ-829, causes behavior wherein dissoc'ing a value with a colliding hashcode from a transient map causes the persistent map from which it was based to be modified as well.

    opened by jordanlewis 0
  • Bump junit from 4.8.2 to 4.13.1

    Bump junit from 4.8.2 to 4.13.1

    Bumps junit from 4.8.2 to 4.13.1.

    Release notes

    Sourced from junit's releases.

    JUnit 4.13.1

    Please refer to the release notes for details.

    JUnit 4.13

    Please refer to the release notes for details.

    JUnit 4.13 RC 2

    Please refer to the release notes for details.

    JUnit 4.13 RC 1

    Please refer to the release notes for details.

    JUnit 4.13 Beta 3

    Please refer to the release notes for details.

    JUnit 4.13 Beta 2

    Please refer to the release notes for details.

    JUnit 4.13 Beta 1

    Please refer to the release notes for details.

    JUnit 4.12

    Please refer to the release notes for details.

    JUnit 4.12 Beta 3

    Please refer to the release notes for details.

    JUnit 4.12 Beta 2

    No release notes provided.

    JUnit 4.12 Beta 1

    No release notes provided.

    JUnit 4.11

    No release notes provided.

    Changelog

    Sourced from junit's changelog.

    Summary of changes in version 4.13.1

    Rules

    Security fix: TemporaryFolder now limits access to temporary folders on Java 1.7 or later

    A local information disclosure vulnerability in TemporaryFolder has been fixed. See the published security advisory for details.

    Test Runners

    [Pull request #1669:](junit-team/junit#1669) Make FrameworkField constructor public

    Prior to this change, custom runners could make FrameworkMethod instances, but not FrameworkField instances. This small change allows for both now, because FrameworkField's constructor has been promoted from package-private to public.

    Commits
    • 1b683f4 [maven-release-plugin] prepare release r4.13.1
    • ce6ce3a Draft 4.13.1 release notes
    • c29dd82 Change version to 4.13.1-SNAPSHOT
    • 1d17486 Add a link to assertThrows in exception testing
    • 543905d Use separate line for annotation in Javadoc
    • 510e906 Add sub headlines to class Javadoc
    • 610155b Merge pull request from GHSA-269g-pwp5-87pp
    • b6cfd1e Explicitly wrap float parameter for consistency (#1671)
    • a5d205c Fix GitHub link in FAQ (#1672)
    • 3a5c6b4 Deprecated since jdk9 replacing constructor instance of Double and Float (#1660)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • [SECURITY] Use HTTPS to resolve dependencies in Maven Build

    [SECURITY] Use HTTPS to resolve dependencies in Maven Build

    mitm_build


    This is a security fix for a vulnerability in your Apache Maven pom.xml file(s).

    The build files indicate that this project is resolving dependencies over HTTP instead of HTTPS. This leaves your build vulnerable to allowing a Man in the Middle (MITM) attackers to execute arbitrary code on your or your computer or CI/CD system.

    This vulnerability has a CVSS v3.0 Base Score of 8.1/10.

    POC code has existed since 2014 to maliciously compromise a JAR file in-flight. MITM attacks against HTTP are increasingly common, for example Comcast is known to have done it to their own users.

    This contribution is a part of a submission to the GitHub Security Lab Bug Bounty program.

    Detecting this and Future Vulnerabilities

    This vulnerability was automatically detected by LGTM.com using this CodeQL Query.

    As of September 2019 LGTM.com and Semmle are officially a part of GitHub.

    You can automatically detect future vulnerabilities like this by enabling the free (for open-source) LGTM App.

    I'm not an employee of GitHub nor of Semmle, I'm simply a user of LGTM.com and an open-source security researcher.

    Source

    Yes, this contribution was automatically generated, however, the code to generate this PR was lovingly hand crafted to bring this security fix to your repository.

    The source code that generated and submitted this PR can be found here: JLLeitschuh/bulk-security-pr-generator

    Opting-Out

    If you'd like to opt-out of future automated security vulnerability fixes like this, please consider adding a file called .github/GH-ROBOTS.txt to your repository with the line:

    User-agent: JLLeitschuh/bulk-security-pr-generator
    Disallow: *
    

    This bot will respect the ROBOTS.txt format for future contributions.

    Alternatively, if this project is no longer actively maintained, consider archiving the repository.

    CLA Requirements

    This section is only relevant if your project requires contributors to sign a Contributor License Agreement (CLA) for external contributions.

    It is unlikely that I'll be able to directly sign CLAs. However, all contributed commits are already automatically signed-off.

    The meaning of a signoff depends on the project, but it typically certifies that committer has the rights to submit this work under the same license and agrees to a Developer Certificate of Origin (see https://developercertificate.org/ for more information).

    - Git Commit Signoff documentation

    If signing your organization's CLA is a strict-requirement for merging this contribution, please feel free to close this PR.

    Tracking

    All PR's generated as part of this fix are tracked here: https://github.com/JLLeitschuh/bulk-security-pr-generator/issues/2

    opened by JLLeitschuh 0
  • Bug in iterators for PersistentVector

    Bug in iterators for PersistentVector

    Hi, I've come across a bug involving iterators for PersistentVectors. The test follows. It happens when you iterate over a vector of length >= 33, but without calling the iterator's "hasNext()" method. (There is no requirement that the hasNext be called if you are sure there is a next element, as far as I know.) If you call the hasNext() method in each iteration the problem goes away.

    package edu.udel.cis.vsl.sarl.collections;

    import java.util.Iterator; import org.junit.Test; import com.github.krukow.clj_ds.PersistentVector; import com.github.krukow.clj_ds.Persistents;

    public class PersistentVectorTest {

    private PersistentVector<Integer> makeVec(int n) {
        PersistentVector<Integer> pv = Persistents.vector();
    
        for (int i = 0; i < n; i++)
            pv = pv.plus(i);
        return pv;
    }
    
    private void check(int n) {
        PersistentVector<Integer> pv = makeVec(n);
        Iterator<Integer> iter = pv.iterator();
    
        for (int i = 0; i < n; i++)
            System.out.println(iter.next());
    }
    
    @Test
    public void test() {
        check(33);
    }
    

    }

    java.lang.ArrayIndexOutOfBoundsException: 32 at com.github.krukow.clj_lang.PersistentVector$PersistentVectorIterator.next(PersistentVector.java:370) at edu.udel.cis.vsl.sarl.collections.PersistentVectorTest.check(PersistentVectorTest.java:25) at edu.udel.cis.vsl.sarl.collections.PersistentVectorTest.test(PersistentVectorTest.java:30) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

    opened by zmanchun 0
  • PersistentHashMap.iterator bug: null key and value in entries

    PersistentHashMap.iterator bug: null key and value in entries

    Occasionally, PersistentHashMap's entry iterator will return an entry whose key and value are both null.

    Running my test case in the debugger, I can see that the map's hasNull value is set to false. Additionally, my code never assocs a null key or value into the map. Running the same test case with PersistentHashMap.iterator2 (the original recursive Seq implementation from Clojure) does not produce entries with null keys or values.

    Unfortunately, I don't have a minimal test case at this time. I'm starting this issue as a placeholder, in case you have or someone else has a good idea of what's going wrong.

    Thoughts?

    opened by jordanlewis 3
Owner
Karl Krukow
GitHub Advanced Security - Code scanning, Director of Engineering.
Karl Krukow
Eclipse Collections is a collections framework for Java with optimized data structures and a rich, functional and fluent API.

English | 中文 | Deutsch | Español | Ελληνικά | Français | 日本語 | Norsk (bokmål) | Português-Brasil | Русский | हिंदी Eclipse Collections is a comprehens

Eclipse Foundation 2.1k Dec 29, 2022
The Java collections framework provides a set of interfaces and classes to implement various data structures and algorithms.

Homework #14 Table of Contents General Info Technologies Used Project Status Contact General Information Homework contains topics: Sorting an ArrayLis

Mykhailo 1 Feb 12, 2022
Table-Computing (Simplified as TC) is a distributed light weighted, high performance and low latency stream processing and data analysis framework. Milliseconds latency and 10+ times faster than Flink for complicated use cases.

Table-Computing Welcome to the Table-Computing GitHub. Table-Computing (Simplified as TC) is a distributed light weighted, high performance and low la

Alibaba 34 Oct 14, 2022
An advanced, but easy to use, platform for writing functional applications in Java 8.

Getting Cyclops X (10) The latest version is cyclops:10.4.0 Stackoverflow tag cyclops-react Documentation (work in progress for Cyclops X) Integration

AOL 1.3k Dec 29, 2022
Library for creating In-memory circular buffers that use direct ByteBuffers to minimize GC overhead

Overview This project aims at creating a simple efficient building block for "Big Data" libraries, applications and frameworks; thing that can be used

Tatu Saloranta 132 Jul 28, 2022
Immutable key/value store with efficient space utilization and fast reads. They are ideal for the use-case of tables built by batch processes and shipped to multiple servers.

Minimal Perfect Hash Tables About Minimal Perfect Hash Tables are an immutable key/value store with efficient space utilization and fast reads. They a

Indeed Engineering 92 Nov 22, 2022
Reading Dalta Lake data from Beam

Reading Delta Lake Data from Beam General Info: All files, except org.apache.beam.sdk.io.DeltaFileIO are from Daltalake Standalone Reader. I was not a

Michael 6 Nov 21, 2022
An embedded database implemented in pure java based on bitcask which is a log-structured hash table for K/V Data.

Baka Db An embedded database implemented in pure java based on bitcask which is a log-structured hash table for K/V Data. Usage import cn.ryoii.baka.B

ryoii 3 Dec 20, 2021
Dremio - the missing link in modern data

Dremio Dremio enables organizations to unlock the value of their data. Documentation Documentation is available at https://docs.dremio.com. Quickstart

Dremio 1.2k Dec 31, 2022
Jalgorithm is an open-source Java library which has implemented various algorithms and data structure

We loved Java and algorithms, so We made Jalgorithm ❤ Jalgorithm is an open-source Java library which has implemented various algorithms and data stru

Muhammad Karbalaee 35 Dec 15, 2022
BioJava is an open-source project dedicated to providing a Java framework for processing biological data.

Welcome to BioJava is an open-source project dedicated to providing a Java framework for processing biological data. It provides analytical and statis

BioJava 513 Dec 31, 2022
SWE5003 - Achitecting Real Time Systems for Data Processing - Code Base

ARTS2022 SWE5003 - Achitecting Real Time Systems for Data Processing (ISS NUS Offering) - Code Base This module is part of the ISS MTech Graduate Cert

Suria R Asai 5 Apr 2, 2022
Enchanted Golden Apple finder for blockgame (can be modified)

[ EgapFinder ] Enchanted Golden Apple finder for Minecraft (can be modified) [ info ] I made this public because I dont play blockgame anymore if you

NudTix 11 Dec 2, 2022
Uses modified Jaro distance to find closest result to search term

Uses modified Jaro distance to find closest result to search term

null 2 Jan 17, 2022
Box86Launcher Is Modified Version Of ptitSeb/box86 Which Runs x86 Version Of WineHQ On Android Nativel

Box86Launcher Box86Launcher Is Modified Version Of ptitSeb/box86 Which Runs x86 Version Of WineHQ On Android Natively. Unlike ExaGear or Running Box86

AkiraYuki 61 Jan 3, 2023
Nginx module for embedding Clojure or Java or Groovy programs, typically those Ring based handlers.

Nginx-Clojure Nginx-Clojure is a Nginx module for embedding Clojure or Java or Groovy programs, typically those Ring based handlers. Core Features The

nginx-clojure 1k Dec 22, 2022
http-kit is a minimalist, event-driven, high-performance Clojure HTTP server/client library with WebSocket and asynchronous support

HTTP Kit A simple, high-performance event-driven HTTP client+server for Clojure CHANGELOG | API | current Break Version: [http-kit "2.5.3"] ; Publish

HTTP Client/Server for Clojure 2.3k Dec 31, 2022
Clojure bindings for the Chromium Embedded Framework

clj-cef Clojure bindings for the Chromium Embedded Framework Dependency: Rationale From https://bitbucket.org/chromiumembedded/cef/src/master/ Some us

Adrian 45 Nov 2, 2022
A Camunda Process Engine Plugin to execute Clojure Functions from Activities

camunda-clojure-plugin A Camunda Process Engine Plugin to execute Clojure Functions as Delegates Why do we need this? While Camunda is tightly integra

lambdaschmiede GmbH 11 Oct 11, 2022