├── .classpath
├── .gitignore
├── .project
├── .settings
└── org.eclipse.jdt.core.prefs
├── README
├── epl-v10.html
├── pom.xml
└── src
├── main
└── java
│ └── com
│ └── github
│ └── krukow
│ ├── clj_ds
│ ├── EditableCollection.java
│ ├── Indexed.java
│ ├── PersistentCollection.java
│ ├── PersistentList.java
│ ├── PersistentMap.java
│ ├── PersistentSet.java
│ ├── PersistentSortedMap.java
│ ├── PersistentSortedSet.java
│ ├── PersistentStack.java
│ ├── PersistentVector.java
│ ├── Persistents.java
│ ├── TransientCollection.java
│ ├── TransientMap.java
│ ├── TransientSet.java
│ ├── TransientVector.java
│ └── Transients.java
│ └── clj_lang
│ ├── AFn.java
│ ├── AFunction.java
│ ├── AMapEntry.java
│ ├── APersistentMap.java
│ ├── APersistentSet.java
│ ├── APersistentTrie.java
│ ├── APersistentVector.java
│ ├── ASeq.java
│ ├── ATransientMap.java
│ ├── ATransientSet.java
│ ├── ArityException.java
│ ├── ArrayChunk.java
│ ├── ArraySeq.java
│ ├── Associative.java
│ ├── BigInt.java
│ ├── Box.java
│ ├── ChunkBuffer.java
│ ├── ChunkedCons.java
│ ├── Cons.java
│ ├── Counted.java
│ ├── EmptyIterator.java
│ ├── Fn.java
│ ├── IChunk.java
│ ├── IChunkedSeq.java
│ ├── IDeref.java
│ ├── IEditableCollection.java
│ ├── IFn.java
│ ├── IHashEq.java
│ ├── ILookup.java
│ ├── IMapEntry.java
│ ├── IMeta.java
│ ├── IObj.java
│ ├── IPending.java
│ ├── IPersistentCollection.java
│ ├── IPersistentList.java
│ ├── IPersistentMap.java
│ ├── IPersistentSet.java
│ ├── IPersistentStack.java
│ ├── IPersistentTrie.java
│ ├── IPersistentVector.java
│ ├── IReduce.java
│ ├── ISeq.java
│ ├── ITransientAssociative.java
│ ├── ITransientCollection.java
│ ├── ITransientMap.java
│ ├── ITransientSet.java
│ ├── ITransientVector.java
│ ├── Indexed.java
│ ├── IndexedSeq.java
│ ├── InlineArrayPersistentHATTrie.java
│ ├── IteratorSeq.java
│ ├── LazilyPersistentVector.java
│ ├── LazySeq.java
│ ├── MapEntry.java
│ ├── Numbers.java
│ ├── Obj.java
│ ├── PersistentArrayMap.java
│ ├── PersistentHATTrie.java
│ ├── PersistentHashMap.java
│ ├── PersistentHashSet.java
│ ├── PersistentList.java
│ ├── PersistentQueue.java
│ ├── PersistentStructMap.java
│ ├── PersistentTreeMap.java
│ ├── PersistentTreeSet.java
│ ├── PersistentVector.java
│ ├── RRBTree.java
│ ├── RT.java
│ ├── Range.java
│ ├── Ratio.java
│ ├── Reduced.java
│ ├── Reflector.java
│ ├── RestFn.java
│ ├── Reversible.java
│ ├── SeqEnumeration.java
│ ├── SeqIterator.java
│ ├── Seqable.java
│ ├── Sequential.java
│ ├── Sorted.java
│ └── Util.java
└── test
└── java
└── com
└── github
└── krukow
└── clj_lang
└── test
├── AllTests.java
├── PersistentHATTrieTest.java
├── PersistentHashMapTest.java
├── PersistentHashSetTest.java
├── PersistentNonHashMapsTest.java
└── PersistentVectorTest.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 | .idea
3 | settings.xml
4 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | clj-ds
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.m2e.core.maven2Builder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.m2e.core.maven2Nature
21 | org.eclipse.jdt.core.javanature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | #Fri May 14 08:04:06 CEST 2010
2 | eclipse.preferences.version=1
3 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6 | org.eclipse.jdt.core.compiler.compliance=1.6
7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
12 | org.eclipse.jdt.core.compiler.source=1.6
13 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | This library has been extracted from the master branch of Clojure (http://clojure.org)
2 |
3 | version 1.5.1 (as of October 2013)
4 |
5 | http://github.com/richhickey/clojure
6 |
7 | created by Rich Hickey. The core data structures and algorithms are due to him.
8 | This library is distributed with the same license as the Clojure programming
9 | language itself (EPL, see file epl-v10.html).
10 |
11 | It has been modified by Karl Krukow , and mistakes introduced are mine.
12 |
13 |
14 | Maven
15 |
16 |
17 | com.github.krukow
18 | clj-ds
19 | 0.0.4
20 |
21 |
22 |
23 | *WHY*
24 | First, I love Clojure :) ...
25 | Unfortunately sometimes clients require that I use Java...
26 |
27 | The data structures used in the Clojure programming language are a great
28 | implementation of a number of useful persistent data structures
29 | (see e.g., the section on immutable data structures on
30 | http://clojure.org/functional_programming).
31 |
32 | However, these data structures are tailor-made to work optimally in the
33 | Clojure programming language, and while it is possible to use these from
34 | Java (since Clojure is distributed as a .jar file), it is inconvenient
35 | for a number of reasons (see below). Since it is (unfortunately) not always
36 | possible to use Clojure, I've created this library to at least reap some of the
37 | Clojure benefits in environments constrained to Java.
38 | Beyond Java, other JVM languages like Erjang, Scala, JRuby and Groovy may benefit
39 | from immutability & persistence, and from this implementation.
40 |
41 | *Advantages of clj-ds when constrained to working with Java*
42 | Currently the Clojure data structures are implemented in Java. In the future,
43 | all of Clojure will be implemented in Clojure itself (known as "Clojure-in-Clojure").
44 | This has many advantages for Clojure, but when it happens the data structures will
45 | probably be even more intertwined with the rest of the language,
46 | and may be even more inconvenient to use in a Java context.
47 |
48 | The clj-ds project will maintain Java versions of the code, and where possible attempt
49 | to "port" improvements made in the Clojure versions back into clj-ds. Thus keeping maintained
50 | versions of the Java data structures.
51 |
52 | In the current Clojure version, calling certain methods on PersistentHashMap requires
53 | loading the entire Clojure runtime, including the bootstrap process. This takes about one second.
54 | This means that the first time one of these methods is called, a Java user will experience a
55 | slight delay (and a memory-usage increase). Further, many of the Clojure runtime
56 | Java classes are not needed when only support for persistent data structures
57 | is wanted (e.g., the compiler).
58 |
59 | The clj-ds library is not dependent on the Clojure runtime nor does it run any
60 | Clojure bootstrap process, e.g., the classes that deal with compilation have been removed.
61 | This results in a smaller library, and the mentioned delay does not occur.
62 |
63 | Clojure is a dynamically typed language. Java is statically typed, and supports
64 | 'generics' from version 5. A Java user would expect generics support from a Java
65 | data structure library, and the Clojure version doesn't have this.
66 | clj-ds will support generics.
67 |
68 | Finally, a slight improvement.
69 | Certain of the Clojure data structure methods use Clojure's 'seq' abstraction
70 | in the implementation of the Java 'iterator' pattern. It is possible, to make
71 | slightly more efficient iterators using a tailor made iterator. clj-ds does this.
72 |
73 | Example stats for iterating through various data structures:
74 | (20-40% improvement, matters only for quite large structures)
75 |
76 | PersistentHashSet:
77 | ----
78 | 500.000 elements
79 | 58 ms (Java avg.)
80 | 192 ms (Pure Clojure avg)
81 | 106 ms (clj-ds avg)
82 | ---
83 | 1 mio elements:
84 | 104 ms (Java avg.)
85 | 497 ms (Pure Clojure avg)
86 | 371 ms (clj-ds avg)
87 |
88 | ---
89 | PersistentHashMap
90 | ---
91 | 500.000 elements
92 | 94 ms (Java avg.)
93 | 189 ms (Pure Clojure avg)
94 | 131 ms (clj-ds avg)
95 |
96 | 1 mio elements:
97 | 128 ms (Java avg.)
98 | 549 ms (Pure Clojure avg)
99 | 394 ms (clj-ds avg)
100 |
101 | ---
102 | PersistentVector
103 | ---
104 | 1 mio elements:
105 | 104 ms (Java avg.)
106 | 122 ms (Pure Clojure avg)
107 | 104 ms (clj-ds avg)
108 |
109 | 2 mio elements:
110 | 186 ms (Java avg.)
111 | 223 ms (Pure Clojure avg)
112 | 184 ms (clj-ds avg)
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 | com.github.krukow
4 | clj-ds
5 | jar
6 | 0.0.5-SNAPSHOT
7 | clj-ds
8 | http://github.com/krukow/clj-ds
9 |
10 | Port of Clojure's data structures to Java
11 |
12 |
13 | UTF-8
14 |
15 |
16 |
17 | org.sonatype.oss
18 | oss-parent
19 | 7
20 |
21 |
22 |
23 |
24 | Eclipse Public License - Version 1.0
25 | http://www.eclipse.org/legal/epl-v10.html
26 | repo
27 |
28 |
29 |
30 |
31 | scm:git:git://github.com/krukow/clj-ds.git
32 | scm:git:git@github.com:krukow/clj-ds.git
33 | http://github.com/krukow/tree/master
34 |
35 |
36 |
37 |
38 |
39 | sonatype-nexus-snapshots
40 | Sonatype Nexus Snapshots
41 | http://oss.sonatype.org/content/repositories/snapshots
42 |
43 |
44 |
45 | sonatype-nexus-staging
46 | Nexus Release Repository
47 | http://oss.sonatype.org/service/local/staging/deploy/maven2/
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | junit
56 | junit
57 | 4.8.2
58 | test
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | org.apache.maven.plugins
67 | maven-compiler-plugin
68 | 2.3.2
69 |
70 | 1.5
71 | 1.5
72 |
73 |
74 |
75 |
76 | org.apache.maven.plugins
77 | maven-resources-plugin
78 | 2.5
79 |
80 | UTF-8
81 |
82 |
83 |
84 |
85 | org.apache.maven.plugins
86 | maven-assembly-plugin
87 | 2.2.2
88 |
89 | gnu
90 |
91 |
92 |
93 |
94 | org.apache.maven.plugins
95 | maven-release-plugin
96 | 2.2.2
97 |
98 | forked-path
99 |
100 |
101 |
102 |
103 | org.apache.maven.plugins
104 | maven-javadoc-plugin
105 | 2.8
106 |
107 | 1.5
108 | 1.5
109 | UTF-8
110 | 1g
111 |
112 | http://java.sun.com/javase/6/docs/api/
113 |
114 |
115 |
116 |
117 | attach-javadocs
118 | verify
119 |
120 | jar
121 |
122 |
123 |
124 |
125 |
126 |
127 | org.apache.maven.plugins
128 | maven-source-plugin
129 | 2.1.2
130 |
131 | true
132 |
133 |
134 |
135 | create-source-jar
136 |
137 | jar-no-fork
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 | release-sign-artifacts
149 |
150 |
151 | performRelease
152 | true
153 |
154 |
155 |
156 |
157 |
158 | org.apache.maven.plugins
159 | maven-gpg-plugin
160 | 1.4
161 |
162 |
163 | sign-artifacts
164 | verify
165 |
166 | sign
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 | krukow
179 | Karl Krukow
180 |
181 |
182 |
183 |
184 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/EditableCollection.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | /**
4 | * A {@link PersistentCollection} implementing this interface indicates that it
5 | * can produce a {@link TransientCollection} for efficient modifications.
6 | */
7 | public interface EditableCollection {
8 |
9 | TransientCollection asTransient();
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/Indexed.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | /**
4 | * This interface add indexed access to elements of a
5 | * {@link PersistentCollection}. "Random-access" runtime characteristics can be
6 | * expected for such collection.
7 | */
8 | public interface Indexed {
9 |
10 | /**
11 | * @return The value at index i
12 | * @throws IndexOutOfBoundsException
13 | * If i is not in the bounds of the collection.
14 | */
15 | E nth(int i);
16 |
17 | /**
18 | * @return The value at index i or the value notFound if i is not in the
19 | * bounds of the collection. This method nether throws an
20 | * {@link IndexOutOfBoundsException}.
21 | */
22 | E nth(int i, E notFound);
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/PersistentCollection.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | import java.util.Collection;
4 |
5 | /**
6 | * The base interface for all persistent data structures. A persistent data
7 | * structure combines immutability with efficient runtime properties. For more
8 | * information read the Persistent Data
10 | * Structure article on Wikipedia.
11 | *
12 | * @param
13 | * The type of objects held in the collection.
14 | */
15 | public interface PersistentCollection extends Collection {
16 |
17 | /**
18 | * @return An empty instance of this kind of collection.
19 | */
20 | PersistentCollection zero();
21 |
22 | /**
23 | * @return A new collection consisting of all elements of the current
24 | * collection together with the value val.
25 | */
26 | PersistentCollection plus(E val);
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/PersistentList.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * A persistent linked list. It implements the {@link List} interface without
7 | * the optional destructive operations.
8 | */
9 | public interface PersistentList extends PersistentStack, List {
10 |
11 | PersistentList zero();
12 |
13 | /**
14 | * @return A new {@link PersistentList} consisting of the value val followed
15 | * by the element of the current {@link PersistentList}.
16 | */
17 | PersistentList plus(E val);
18 |
19 | /**
20 | * @return A new {@link PersistentList} consisting of the elements of the current
21 | * {@link PersistentList} without its first element.
22 | */
23 | PersistentList minus();
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/PersistentMap.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | import java.util.Map;
4 |
5 | /**
6 | * {@link PersistentMap}s
7 | *
8 | * @param
9 | * The type of the keys
10 | * @param
11 | * The type of the values
12 | */
13 | public interface PersistentMap extends Map {
14 |
15 | /**
16 | * @return An empty instance of this kind of {@link PersistentMap}
17 | */
18 | PersistentMap zero();
19 |
20 | /**
21 | * @return A new {@link PersistentMap} consisting of the content of the
22 | * current {@link PersistentMap} where the given key is associated
23 | * to the value val. The new association may replace a previous
24 | * association.
25 | */
26 | PersistentMap plus(K key, V val);
27 |
28 | /**
29 | * @return A new {@link PersistentMap} consisting of the content of the
30 | * current {@link PersistentMap} where the given key is associated
31 | * to the value val.
32 | * @throws java.lang.RuntimeException
33 | * If the key is already present in the {@link PersistentMap}.
34 | */
35 | PersistentMap plusEx(K key, V val);
36 |
37 | /**
38 | * @return A new {@link PersistentMap} consisting of the content of the
39 | * current {@link PersistentMap} without the assocation to the given
40 | * key.
41 | */
42 | PersistentMap minus(K key);
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/PersistentSet.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | import java.util.Set;
4 |
5 | public interface PersistentSet extends PersistentCollection, Set, EditableCollection {
6 |
7 | PersistentSet zero();
8 |
9 | PersistentSet plus(E val);
10 |
11 | /**
12 | * @return A new {@link PersistentSet} that consists of the elements of the
13 | * current {@link PersistentSet} without the value val.
14 | */
15 | PersistentSet minus(E val);
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/PersistentSortedMap.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | import com.github.krukow.clj_lang.Sorted;
4 |
5 | public interface PersistentSortedMap extends PersistentMap, Sorted /* , SortedMap */{
6 |
7 | PersistentSortedMap zero();
8 |
9 | PersistentSortedMap plus(K key, V val);
10 |
11 | PersistentSortedMap plusEx(K key, V val);
12 |
13 | PersistentSortedMap minus(K key);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/PersistentSortedSet.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | import com.github.krukow.clj_lang.Sorted;
4 |
5 | public interface PersistentSortedSet extends PersistentSet, Sorted /*, SortedSet */ {
6 |
7 | PersistentSortedSet zero();
8 |
9 | PersistentSortedSet plus(E o);
10 |
11 | PersistentSortedSet minus(E key);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/PersistentStack.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | public interface PersistentStack extends PersistentCollection {
4 |
5 | PersistentStack zero();
6 |
7 | PersistentStack plus(E o);
8 |
9 | /**
10 | * @return A new stack consisting of the current stack without its top
11 | * element.
12 | */
13 | PersistentStack minus();
14 |
15 | /**
16 | * @return The top element of this stack.
17 | */
18 | E peek();
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/PersistentVector.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * A {@link PersistentCollection} that has array-like runtime characteritics.
7 | * New elements are "added" at the end of the {@link PersistentVector}.
8 | */
9 | public interface PersistentVector extends PersistentStack, List, Indexed, Comparable, EditableCollection {
10 |
11 | PersistentVector zero();
12 |
13 | /**
14 | * @return A new {@link PersistentVector} consisting of the elements of the
15 | * current {@link PersistentVector} followed by the value val.
16 | */
17 | PersistentVector plus(E val);
18 |
19 | /**
20 | * @return A new {@link PersistentVector} consisting of the elements of
21 | * current {@link PersistentVector} where the element at index i has
22 | * been replaced by the value val.
23 | * @throw {@link IndexOutOfBoundsException} if the index i is greater that
24 | * the current maximum index.
25 | */
26 | PersistentVector plusN(int i, E val);
27 |
28 | /**
29 | * @return A new {@link PersistentVector} consisting of the elements of
30 | * the current {@link PersistentVector} without its last element.
31 | */
32 | PersistentVector minus();
33 |
34 | TransientVector asTransient();
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/Persistents.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | import java.util.Iterator;
4 | import java.util.Map;
5 |
6 | import com.github.krukow.clj_lang.PersistentArrayMap;
7 | import com.github.krukow.clj_lang.PersistentHashMap;
8 | import com.github.krukow.clj_lang.PersistentHashSet;
9 | import com.github.krukow.clj_lang.PersistentTreeMap;
10 | import com.github.krukow.clj_lang.PersistentTreeSet;
11 |
12 | public final class Persistents {
13 |
14 | // Factory Methods
15 |
16 | /**
17 | * @return An empty {@link PersistentVector}.
18 | */
19 | public static PersistentVector vector() {
20 | return com.github.krukow.clj_lang.PersistentVector.emptyVector();
21 | }
22 |
23 | /**
24 | * @return A singleton {@link PersistentVector} with the value val.
25 | */
26 | public static PersistentVector vector(E val) {
27 | return Persistents. vector().plus(val);
28 | }
29 |
30 | /**
31 | * @return A {@link PersistentVector} consisting of the elements of the
32 | * array vals.
33 | */
34 | public static PersistentVector vector(E... vals) {
35 | return com.github.krukow.clj_lang.PersistentVector.create(vals);
36 | }
37 |
38 | /**
39 | * @return A {@link PersistentVector} consisting of the elements of the
40 | * {@link Iterable} vals
41 | */
42 | public static PersistentVector vector(Iterable extends E> vals) {
43 | return com.github.krukow.clj_lang.PersistentVector.create(vals);
44 | }
45 |
46 | /**
47 | * @return An empty {@link PersistentSet}; implemented as hash set.
48 | */
49 | public static PersistentSet hashSet() {
50 | return PersistentHashSet.emptySet();
51 | }
52 |
53 | /**
54 | * @return A singleton {@link PersistentSet} with the value val; implemented
55 | * as hash set.
56 | */
57 | public static PersistentSet hashSet(E val) {
58 | return Persistents. hashSet().plus(val);
59 | }
60 |
61 | /**
62 | * @return A {@link PersistentSet} consisting of the elements of the array
63 | * vals; implemented as hash set.
64 | */
65 | public static PersistentSet hashSet(E... vals) {
66 | return PersistentHashSet.create(vals);
67 | }
68 |
69 | /**
70 | * @return A {@link PersistentSet} consisting of the elements of the
71 | * {@link Iterable} vals; implemented as hash set.
72 | */
73 | public static PersistentSet hashSet(Iterable extends E> vals) {
74 | return PersistentHashSet.create(vals);
75 | }
76 |
77 | /**
78 | * @return An empty {@link PersistentMap}; implemented as hash map.
79 | */
80 | public static PersistentMap hashMap() {
81 | return PersistentHashMap.emptyMap();
82 | }
83 |
84 | /**
85 | * @return A singleton {@link PersistentMap} associating the given key with
86 | * the given value; implemented as hash map.
87 | */
88 | public static PersistentMap hashMap(K key, V val) {
89 | return Persistents. hashMap().plus(key, val);
90 | }
91 |
92 | /**
93 | * @param keyValues
94 | * An array containing key/value pairs; no type checking is made.
95 | * @return A {@link PersistentMap} with the given associations; implemented
96 | * as hash map.
97 | */
98 | public static PersistentMap hashMap(Object... keyValues) {
99 | return PersistentHashMap.create(keyValues);
100 | }
101 |
102 | /**
103 | * @return A {@link PersistentMap} consisting of the associations of the map
104 | * init; implemented as hash map.
105 | */
106 | public static PersistentMap hashMap(Map extends K, ? extends V> init) {
107 | return PersistentHashMap.create(init);
108 | }
109 |
110 | /**
111 | * @return An empty {@link PersistentMap}; implemented as array map.
112 | */
113 | @SuppressWarnings("unchecked")
114 | public static PersistentMap arrayMap() {
115 | return PersistentArrayMap.EMPTY;
116 | }
117 |
118 | /**
119 | * @return A {@link PersistentMap} consisting of the associations of the map
120 | * init; implemented as array map.
121 | */
122 | public static PersistentMap arrayMap(Map extends K, ? extends V> init) {
123 | return PersistentArrayMap.create(init);
124 | }
125 |
126 | /**
127 | * @return An empty {@link PersistentSortedMap}; implemented as a tree map.
128 | */
129 | @SuppressWarnings("unchecked")
130 | public static PersistentSortedMap treeMap() {
131 | return PersistentTreeMap.EMPTY;
132 | }
133 |
134 | /**
135 | * @return A singleton {@link PersistentSortedMap} associating the given key
136 | * with the given value; implemented as tree map.
137 | */
138 | public static PersistentSortedMap treeMap(K key, V val) {
139 | return Persistents. treeMap().plus(key, val);
140 | }
141 |
142 | /**
143 | * @return A {@link PersistentSortedMap} consisting of the associations of
144 | * the map init; implemented as tree map.
145 | */
146 | public static PersistentSortedMap treeMap(Map extends K, ? extends V> init) {
147 | return PersistentTreeMap.create(init);
148 | }
149 |
150 | /**
151 | * @return An empty {@link PersistentSortedSet}; implemented as tree set.
152 | */
153 | @SuppressWarnings("unchecked")
154 | public static PersistentSortedSet treeSet() {
155 | return PersistentTreeSet.EMPTY;
156 | }
157 |
158 | /**
159 | * @return An empty {@link PersistentList}; implemented as linked list.
160 | */
161 | public static PersistentList linkedList() {
162 | return com.github.krukow.clj_lang.PersistentList.emptyList();
163 | }
164 |
165 | /**
166 | * @return An singleton {@link PersistentList} with the value val;
167 | * implemented as linked list.
168 | */
169 | public static PersistentList linkedList(E val) {
170 | return Persistents. linkedList().plus(val);
171 | }
172 |
173 | /**
174 | * @return A {@link PersistentList} consisting of the element of the array
175 | * vals; implemented as linked list.
176 | */
177 | public static PersistentList linkedList(E... vals) {
178 | return com.github.krukow.clj_lang.PersistentList.create(vals);
179 | }
180 |
181 | /**
182 | * @return A {@link PersistentList} consisting of the element of the
183 | * {@link Iterator} vals; implemented as linked list.
184 | */
185 | public static PersistentList linkedList(Iterable extends E> vals) {
186 | return com.github.krukow.clj_lang.PersistentList.create(vals);
187 | }
188 |
189 | // Utilities
190 |
191 | /**
192 | * Applies successively the method {@link PersistentList#plus(E)}.
193 | */
194 | public static PersistentList plusAll(PersistentList list, Iterable extends E> others) {
195 | return com.github.krukow.clj_lang.PersistentList.consAll(list, others);
196 | }
197 |
198 | /**
199 | * Applies successively the method {@link PersistentList#plus(E)}.
200 | */
201 | public static PersistentList plusAll(PersistentList list, E... others) {
202 | PersistentList result = list;
203 | for (E other : others) {
204 | result = result.plus(other);
205 | }
206 | return result;
207 | }
208 |
209 | /**
210 | * Applies successively the method {@link PersistentVector#plus(E)}.
211 | */
212 | public static PersistentVector plusAll(PersistentVector vec, Iterable extends E> others) {
213 | TransientVector result = vec.asTransient();
214 | for (E other : others) {
215 | result = result.plus(other);
216 | }
217 | return result.persist();
218 | }
219 |
220 | /**
221 | * Applies successively the method {@link PersistentVector#plus(E)}.
222 | */
223 | public static PersistentVector plusAll(PersistentVector vec, E... others) {
224 | TransientVector result = vec.asTransient();
225 | for (E other : others) {
226 | result = result.plus(other);
227 | }
228 | return result.persist();
229 | }
230 |
231 | /**
232 | * Applies successively the method {@link PersistentSet#plus(E)}.
233 | */
234 | public static PersistentSet plusAll(PersistentSet set, Iterable extends E> others) {
235 | TransientSet result = (TransientSet) set.asTransient();
236 | for (E other : others) {
237 | result = result.plus(other);
238 | }
239 | return result.persist();
240 | }
241 |
242 | /**
243 | * Applies successively the method {@link PersistentSet#plus(E)}.
244 | */
245 | public static PersistentSet plusAll(PersistentSet set, E... others) {
246 | TransientSet result = (TransientSet) set.asTransient();
247 | for (E other : others) {
248 | result = result.plus(other);
249 | }
250 | return result.persist();
251 | }
252 |
253 | /**
254 | * Applies successively the method {@link PersistentSet#minus(E)}.
255 | */
256 | public static PersistentSet minusAll(PersistentSet set, Iterable extends E> others) {
257 | TransientSet result = (TransientSet) set.asTransient();
258 | for (E other : others) {
259 | result = result.minus(other);
260 | }
261 | return result.persist();
262 | }
263 |
264 | /**
265 | * Applies successively the method {@link PersistentSet#minus(E)}.
266 | */
267 | public static PersistentSet minusAll(PersistentSet set, E... others) {
268 | TransientSet result = (TransientSet) set.asTransient();
269 | for (E other : others) {
270 | result = result.minus(other);
271 | }
272 | return result.persist();
273 | }
274 |
275 | /**
276 | * Applies successively the method {@link PersistentSortedSet#plus(E)}.
277 | */
278 | public static PersistentSortedSet plusAll(PersistentSortedSet set, Iterable extends E> others) {
279 | PersistentSortedSet result = set;
280 | for (E other : others) {
281 | result = result.plus(other);
282 | }
283 | return result;
284 | }
285 |
286 | /**
287 | * Applies successively the method {@link PersistentSortedSet#plus(E)}.
288 | */
289 | public static PersistentSortedSet plusAll(PersistentSortedSet set, E... others) {
290 | PersistentSortedSet result = set;
291 | for (E other : others) {
292 | result = result.plus(other);
293 | }
294 | return result;
295 | }
296 |
297 | /**
298 | * Applies successively the method {@link PersistentSortedSet#minus(E)}.
299 | */
300 | public static PersistentSortedSet minusAll(PersistentSortedSet set, Iterable extends E> others) {
301 | PersistentSortedSet result = set;
302 | for (E other : others) {
303 | result = result.minus(other);
304 | }
305 | return result;
306 | }
307 |
308 | /**
309 | * Applies successively the method {@link PersistentSortedSet#minus(E)}.
310 | */
311 | public static PersistentSortedSet minusAll(PersistentSortedSet set, E... others) {
312 | PersistentSortedSet result = set;
313 | for (E other : others) {
314 | result = result.minus(other);
315 | }
316 | return result;
317 | }
318 |
319 | // Empty Constructor
320 | private Persistents() {
321 | }
322 |
323 | }
324 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/TransientCollection.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | /**
4 | * A {@link TransientCollection} is a collection that does not retain older
5 | * versions in order to gain efficient modifications. To manipulate a
6 | * {@link TransientCollection}, one must still used the new values produced by
7 | * the "destructive" operations plus, minus, etc. However, no guarantees are
8 | * made on the previous values of the collection.
9 | */
10 | public interface TransientCollection {
11 |
12 | /**
13 | * @return A new {@link TransientCollection} consisting of all the elements
14 | * of the current collection together with the value val (no
15 | * guarantees are made on the current collection).
16 | */
17 | TransientCollection plus(E val);
18 |
19 | /**
20 | * @return A corresponding {@link PersistentCollection} consisting of the
21 | * elements of the current {@link TransientCollection}.
22 | */
23 | PersistentCollection persist();
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/TransientMap.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | public interface TransientMap {
4 |
5 | /**
6 | * @return A new {@link PersistentMap} consisting of the content of the
7 | * current {@link PersistentMap} where the given key is associated
8 | * to the value val (no guarantees are made on the current map). The
9 | * new association may replace a previous association.
10 | */
11 | TransientMap plus(K key, V val);
12 |
13 | /**
14 | * @return A new {@link PersistentMap} consisting of the content of the
15 | * current {@link PersistentMap} without the association to the
16 | * given key (no guarantees are made on the current map).
17 | */
18 | TransientMap minus(K key);
19 |
20 | PersistentMap persist();
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/TransientSet.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | public interface TransientSet extends TransientCollection {
4 |
5 | TransientSet plus(E val);
6 |
7 | /**
8 | * @return A new {@link TransientSet} consisting of all the elements of the
9 | * current collection without the value val (no guarantees are made
10 | * on the current set).
11 | */
12 | TransientSet minus(E val);
13 |
14 | PersistentSet persist();
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/TransientVector.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | public interface TransientVector extends TransientCollection, Indexed {
4 |
5 | /**
6 | * @return A new {@link TransientVector} consisting of the elements of the
7 | * current {@link TransientVector} followed by the value val. (no
8 | * guarantees are made on the current collection).
9 | */
10 | TransientVector plus(E val);
11 |
12 | /**
13 | * @return A new {@link TransientVector} consisting of the elements of
14 | * current {@link TransientSet} where the element at index i has
15 | * been replaced by the value val (no guarantees are made on the
16 | * current collection).
17 | * @throw {@link IndexOutOfBoundsException} if the index i is greater that
18 | * the current maximum index.
19 | */
20 | TransientVector plusN(int i, E val);
21 |
22 | /**
23 | * @return A new {@link TransientVector} consisting of the elements of the
24 | * current collection together with its last element (no guarantees
25 | * are made on the current collection).
26 | */
27 | TransientVector minus();
28 |
29 | TransientVector pop();
30 |
31 | PersistentVector persist();
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_ds/Transients.java:
--------------------------------------------------------------------------------
1 | package com.github.krukow.clj_ds;
2 |
3 | import com.github.krukow.clj_lang.PersistentArrayMap;
4 | import com.github.krukow.clj_lang.PersistentHashMap;
5 | import com.github.krukow.clj_lang.PersistentHashSet;
6 | import com.github.krukow.clj_lang.PersistentVector;
7 |
8 | public final class Transients {
9 |
10 | // Factory Methods
11 |
12 | public static final TransientVector transientVector() {
13 | return PersistentVector.emptyVector().asTransient();
14 | }
15 |
16 | public static final TransientSet transientHashSet() {
17 | return PersistentHashSet.emptySet().asTransient();
18 | }
19 |
20 | @SuppressWarnings("unchecked")
21 | public static final TransientMap transientHashMap() {
22 | return PersistentHashMap.emptyMap().asTransient();
23 | }
24 |
25 | @SuppressWarnings("unchecked")
26 | public static final TransientMap transientArrayMap() {
27 | return PersistentArrayMap.EMPTY.asTransient();
28 | }
29 |
30 | // Utilities
31 |
32 | public static TransientVector plusAll(TransientVector vec, Iterable extends E> others) {
33 | TransientVector tv = vec;
34 | for (E other : others) {
35 | tv = tv.plus(other);
36 | }
37 | return tv;
38 | }
39 |
40 | public static TransientVector plusAll(TransientVector vec, E... others) {
41 | TransientVector tv = vec;
42 | for (E other : others) {
43 | tv = tv.plus(other);
44 | }
45 | return tv;
46 | }
47 |
48 | public static TransientSet plusAll(TransientSet set, Iterable extends E> others) {
49 | TransientSet tv = set;
50 | for (E other : others) {
51 | tv = tv.plus(other);
52 | }
53 | return tv;
54 | }
55 |
56 | public static TransientSet plusAll(TransientSet set, E... others) {
57 | TransientSet tv = set;
58 | for (E other : others) {
59 | tv = tv.plus(other);
60 | }
61 | return tv;
62 | }
63 |
64 | public static TransientSet minusAll(TransientSet set, Iterable extends E> others) {
65 | TransientSet tv = set;
66 | for (E other : others) {
67 | tv = tv.minus(other);
68 | }
69 | return tv;
70 | }
71 |
72 | private Transients() {
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_lang/AFunction.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Rich Hickey. All rights reserved.
3 | * The use and distribution terms for this software are covered by the
4 | * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5 | * which can be found in the file epl-v10.html at the root of this distribution.
6 | * By using this software in any fashion, you are agreeing to be bound by
7 | * the terms of this license.
8 | * You must not remove this notice, or any other, from this software.
9 | **/
10 |
11 | /* rich Dec 16, 2008 */
12 |
13 | package com.github.krukow.clj_lang;
14 |
15 | import java.io.Serializable;
16 | import java.util.Comparator;
17 |
18 | public abstract class AFunction extends AFn implements IObj, Comparator, Fn, Serializable {
19 |
20 | public IPersistentMap meta(){
21 | return null;
22 | }
23 |
24 | public IObj withMeta(final IPersistentMap meta){
25 | return new RestFn(){
26 | protected Object doInvoke(Object args) {
27 | return AFunction.this.applyTo((ISeq) args);
28 | }
29 |
30 | public IPersistentMap meta(){
31 | return meta;
32 | }
33 |
34 | public IObj withMeta(IPersistentMap meta){
35 | return AFunction.this.withMeta(meta);
36 | }
37 |
38 | public int getRequiredArity(){
39 | return 0;
40 | }
41 | };
42 | }
43 |
44 | public int compare(Object o1, Object o2){
45 | try
46 | {
47 | Object o = invoke(o1, o2);
48 |
49 | if(o instanceof Boolean)
50 | {
51 | if(RT.booleanCast(o))
52 | return -1;
53 | return RT.booleanCast(invoke(o2,o1))? 1 : 0;
54 | }
55 |
56 | Number n = (Number) o;
57 | return n.intValue();
58 | }
59 | catch(Exception e)
60 | {
61 | throw Util.sneakyThrow(e);
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_lang/AMapEntry.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Rich Hickey. All rights reserved.
3 | * The use and distribution terms for this software are covered by the
4 | * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5 | * which can be found in the file epl-v10.html at the root of this distribution.
6 | * By using this software in any fashion, you are agreeing to be bound by
7 | * the terms of this license.
8 | * You must not remove this notice, or any other, from this software.
9 | **/
10 |
11 | /* rich Mar 1, 2008 */
12 |
13 | package com.github.krukow.clj_lang;
14 |
15 |
16 | public abstract class AMapEntry extends APersistentVector implements IMapEntry{
17 |
18 | public Object nth(int i){
19 | if(i == 0)
20 | return key();
21 | else if(i == 1)
22 | return val();
23 | else
24 | throw new IndexOutOfBoundsException();
25 | }
26 |
27 | private IPersistentVector asVector(){
28 | return LazilyPersistentVector.createOwning(key(), val());
29 | }
30 |
31 | public IPersistentVector assocN(int i, Object val){
32 | return asVector().assocN(i, val);
33 | }
34 |
35 | public int count(){
36 | return 2;
37 | }
38 |
39 | public ISeq seq(){
40 | return asVector().seq();
41 | }
42 |
43 | public IPersistentVector cons(Object o){
44 | return asVector().cons(o);
45 | }
46 |
47 | public IPersistentCollection empty(){
48 | return null;
49 | }
50 |
51 | public IPersistentStack pop(){
52 | return LazilyPersistentVector.createOwning(key());
53 | }
54 |
55 | public Object setValue(Object value){
56 | throw new UnsupportedOperationException();
57 | }
58 |
59 | /*
60 |
61 | public boolean equals(Object obj){
62 | return APersistentVector.doEquals(this, obj);
63 | }
64 |
65 | public int hashCode(){
66 | //must match logic in APersistentVector
67 | return 31 * (31 + Util.hash(key())) + Util.hash(val());
68 | // return Util.hashCombine(Util.hashCombine(0, Util.hash(key())), Util.hash(val()));
69 | }
70 |
71 | public String toString(){
72 | StringWriter sw = new StringWriter();
73 | try
74 | {
75 | RT.print(this, sw);
76 | }
77 | catch(Exception e)
78 | {
79 | //checked exceptions stink!
80 | throw Util.sneakyThrow(e);
81 | }
82 | return sw.toString();
83 | }
84 |
85 | public int length(){
86 | return 2;
87 | }
88 |
89 | public Object nth(int i){
90 | if(i == 0)
91 | return key();
92 | else if(i == 1)
93 | return val();
94 | else
95 | throw new IndexOutOfBoundsException();
96 | }
97 |
98 | private IPersistentVector asVector(){
99 | return LazilyPersistentVector.createOwning(key(), val());
100 | }
101 |
102 | public IPersistentVector assocN(int i, Object val){
103 | return asVector().assocN(i, val);
104 | }
105 |
106 | public int count(){
107 | return 2;
108 | }
109 |
110 | public ISeq seq(){
111 | return asVector().seq();
112 | }
113 |
114 | public IPersistentVector cons(Object o){
115 | return asVector().cons(o);
116 | }
117 |
118 | public boolean containsKey(Object key){
119 | return asVector().containsKey(key);
120 | }
121 |
122 | public IMapEntry entryAt(Object key){
123 | return asVector().entryAt(key);
124 | }
125 |
126 | public Associative assoc(Object key, Object val){
127 | return asVector().assoc(key, val);
128 | }
129 |
130 | public Object valAt(Object key){
131 | return asVector().valAt(key);
132 | }
133 |
134 | public Object valAt(Object key, Object notFound){
135 | return asVector().valAt(key, notFound);
136 | }
137 |
138 | public Object peek(){
139 | return val();
140 | }
141 |
142 |
143 | public ISeq rseq() {
144 | return asVector().rseq();
145 | }
146 | */
147 |
148 | }
149 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_lang/APersistentMap.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Rich Hickey. All rights reserved.
3 | * The use and distribution terms for this software are covered by the
4 | * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5 | * which can be found in the file epl-v10.html at the root of this distribution.
6 | * By using this software in any fashion, you are agreeing to be bound by
7 | * the terms of this license.
8 | * You must not remove this notice, or any other, from this software.
9 | **/
10 |
11 | package com.github.krukow.clj_lang;
12 |
13 | import java.io.Serializable;
14 | import java.util.AbstractCollection;
15 | import java.util.AbstractSet;
16 | import java.util.Collection;
17 | import java.util.Iterator;
18 | import java.util.Map;
19 | import java.util.Set;
20 |
21 | public abstract class APersistentMap extends AFn implements IPersistentMap, Map, Iterable>, Serializable, IHashEq {
22 | int _hash = -1;
23 | int _hasheq = -1;
24 |
25 | public String toString(){
26 | return RT.printString(this);
27 | }
28 |
29 | public IPersistentCollection cons(IMapEntry o){
30 | return assoc(o.getKey(), o.getValue());
31 | }
32 |
33 | public boolean equals(Object obj){
34 | if(this == obj) return true;
35 | if(!(obj instanceof Map))
36 | return false;
37 | Map m = (Map) obj;
38 |
39 | if(m.size() != size())
40 | return false;
41 |
42 | for(ISeq s = seq(); s != null; s = s.next())
43 | {
44 | Map.Entry e = (Map.Entry) s.first();
45 | boolean found = m.containsKey(e.getKey());
46 |
47 | if(!found || !Util.equals(e.getValue(), m.get(e.getKey())))
48 | return false;
49 | }
50 |
51 | return true;
52 | }
53 |
54 | public boolean equiv(Object obj){
55 | if(!(obj instanceof Map))
56 | return false;
57 | Map m = (Map) obj;
58 |
59 | if(m.size() != size())
60 | return false;
61 |
62 | for(ISeq s = seq(); s != null; s = s.next())
63 | {
64 | Map.Entry e = (Map.Entry) s.first();
65 | boolean found = m.containsKey(e.getKey());
66 |
67 | if(!found || !Util.equiv(e.getValue(), m.get(e.getKey())))
68 | return false;
69 | }
70 |
71 | return true;
72 | }
73 | public int hashCode(){
74 | if(_hash == -1)
75 | {
76 | int hash = 0;
77 | for(ISeq s = seq(); s != null; s = s.next())
78 | {
79 | Map.Entry e = (Map.Entry) s.first();
80 | hash += (e.getKey() == null ? 0 : e.getKey().hashCode()) ^
81 | (e.getValue() == null ? 0 : e.getValue().hashCode());
82 | }
83 | this._hash = hash;
84 | }
85 | return _hash;
86 | }
87 |
88 | public int hasheq(){
89 | if(_hasheq == -1)
90 | {
91 | int hash = 0;
92 | for(ISeq s = seq(); s != null; s = s.next())
93 | {
94 | Map.Entry e = (Map.Entry) s.first();
95 | hash += Util.hasheq(e.getKey()) ^
96 | Util.hasheq(e.getValue());
97 | }
98 | this._hasheq = hash;
99 | }
100 | return _hasheq;
101 | }
102 |
103 | static public class KeySeq extends ASeq{
104 | ISeq seq;
105 |
106 | static public KeySeq create(ISeq seq){
107 | if(seq == null)
108 | return null;
109 | return new KeySeq(seq);
110 | }
111 |
112 | private KeySeq(ISeq seq){
113 | this.seq = seq;
114 | }
115 |
116 | private KeySeq(IPersistentMap meta, ISeq seq){
117 | super(meta);
118 | this.seq = seq;
119 | }
120 |
121 | public Object first(){
122 | return ((Map.Entry) seq.first()).getKey();
123 | }
124 |
125 | public ISeq next(){
126 | return create(seq.next());
127 | }
128 |
129 | public KeySeq withMeta(IPersistentMap meta){
130 | return new KeySeq(meta, seq);
131 | }
132 | }
133 |
134 | static public class ValSeq extends ASeq{
135 | ISeq seq;
136 |
137 | static public ValSeq create(ISeq seq){
138 | if(seq == null)
139 | return null;
140 | return new ValSeq(seq);
141 | }
142 |
143 | private ValSeq(ISeq seq){
144 | this.seq = seq;
145 | }
146 |
147 | private ValSeq(IPersistentMap meta, ISeq seq){
148 | super(meta);
149 | this.seq = seq;
150 | }
151 |
152 | public Object first(){
153 | return ((Map.Entry) seq.first()).getValue();
154 | }
155 |
156 | public ISeq next(){
157 | return create(seq.next());
158 | }
159 |
160 | public ValSeq withMeta(IPersistentMap meta){
161 | return new ValSeq(meta, seq);
162 | }
163 | }
164 |
165 |
166 | public Object invoke(Object arg1) {
167 | return valAt((K) arg1);
168 | }
169 |
170 | public Object invoke(Object arg1, Object notFound) {
171 | return valAt((K) arg1, (V) notFound);
172 | }
173 |
174 | // java.util.Map implementation
175 |
176 | public void clear(){
177 | throw new UnsupportedOperationException();
178 | }
179 |
180 | public boolean containsValue(Object value){
181 | return values().contains(value);
182 | }
183 |
184 | public Set> entrySet(){
185 | return new AbstractSet>(){
186 |
187 | public Iterator> iterator(){
188 | return APersistentMap.this.iterator();
189 | }
190 |
191 | public int size(){
192 | return count();
193 | }
194 |
195 | public int hashCode(){
196 | return APersistentMap.this.hashCode();
197 | }
198 |
199 | public boolean contains(Object o){
200 | if(o instanceof Entry)
201 | {
202 | Entry e = (Entry) o;
203 | Entry found = entryAt((K) e.getKey());
204 | if(found != null && Util.equals(found.getValue(), e.getValue()))
205 | return true;
206 | }
207 | return false;
208 | }
209 | };
210 | }
211 |
212 | public V get(Object key){
213 | return valAt((K) key);
214 | }
215 |
216 | public boolean isEmpty(){
217 | return count() == 0;
218 | }
219 |
220 | public Set keySet(){
221 | return new AbstractSet(){
222 |
223 | public Iterator iterator(){
224 | final Iterator> mi = APersistentMap.this.iterator();
225 |
226 | return new Iterator(){
227 |
228 |
229 | public boolean hasNext(){
230 | return mi.hasNext();
231 | }
232 |
233 | public K next(){
234 | Entry e = (Entry) mi.next();
235 | return e.getKey();
236 | }
237 |
238 | public void remove(){
239 | throw new UnsupportedOperationException();
240 | }
241 | };
242 | }
243 |
244 | public int size(){
245 | return count();
246 | }
247 |
248 | public boolean contains(Object o){
249 | return APersistentMap.this.containsKey(o);
250 | }
251 | };
252 | }
253 |
254 | public V put(K key, V value){
255 | throw new UnsupportedOperationException();
256 | }
257 |
258 | public void putAll(Map t){
259 | throw new UnsupportedOperationException();
260 | }
261 |
262 | public V remove(Object key){
263 | throw new UnsupportedOperationException();
264 | }
265 |
266 | public int size(){
267 | return count();
268 | }
269 |
270 | public Collection values(){
271 | return new AbstractCollection(){
272 |
273 | public Iterator iterator(){
274 | final Iterator> mi = APersistentMap.this.iterator();
275 |
276 | return new Iterator(){
277 |
278 |
279 | public boolean hasNext(){
280 | return mi.hasNext();
281 | }
282 |
283 | public V next(){
284 | return mi.next().getValue();
285 | }
286 |
287 | public void remove(){
288 | throw new UnsupportedOperationException();
289 | }
290 | };
291 | }
292 |
293 | public int size(){
294 | return count();
295 | }
296 | };
297 | }
298 |
299 | /*
300 | // java.util.Collection implementation
301 |
302 | public Object[] toArray(){
303 | return RT.seqToArray(seq());
304 | }
305 |
306 | public boolean add(Object o){
307 | throw new UnsupportedOperationException();
308 | }
309 |
310 | public boolean remove(Object o){
311 | throw new UnsupportedOperationException();
312 | }
313 |
314 | public boolean addAll(Collection c){
315 | throw new UnsupportedOperationException();
316 | }
317 |
318 | public void clear(){
319 | throw new UnsupportedOperationException();
320 | }
321 |
322 | public boolean retainAll(Collection c){
323 | throw new UnsupportedOperationException();
324 | }
325 |
326 | public boolean removeAll(Collection c){
327 | throw new UnsupportedOperationException();
328 | }
329 |
330 | public boolean containsAll(Collection c){
331 | for(Object o : c)
332 | {
333 | if(!contains(o))
334 | return false;
335 | }
336 | return true;
337 | }
338 |
339 | public Object[] toArray(Object[] a){
340 | if(a.length >= count())
341 | {
342 | ISeq s = seq();
343 | for(int i = 0; s != null; ++i, s = s.rest())
344 | {
345 | a[i] = s.first();
346 | }
347 | if(a.length > count())
348 | a[count()] = null;
349 | return a;
350 | }
351 | else
352 | return toArray();
353 | }
354 |
355 | public int size(){
356 | return count();
357 | }
358 |
359 | public boolean isEmpty(){
360 | return count() == 0;
361 | }
362 |
363 | public boolean contains(Object o){
364 | if(o instanceof Map.Entry)
365 | {
366 | Map.Entry e = (Map.Entry) o;
367 | Map.Entry v = entryAt(e.getKey());
368 | return (v != null && Util.equal(v.getValue(), e.getValue()));
369 | }
370 | return false;
371 | }
372 | */
373 | }
374 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_lang/APersistentSet.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Rich Hickey. All rights reserved.
3 | * The use and distribution terms for this software are covered by the
4 | * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5 | * which can be found in the file epl-v10.html at the root of this distribution.
6 | * By using this software in any fashion, you are agreeing to be bound by
7 | * the terms of this license.
8 | * You must not remove this notice, or any other, from this software.
9 | **/
10 |
11 | /* rich Mar 3, 2008 */
12 |
13 | package com.github.krukow.clj_lang;
14 |
15 | import java.io.Serializable;
16 | import java.util.Collection;
17 | import java.util.Iterator;
18 | import java.util.Set;
19 |
20 | public abstract class APersistentSet extends AFn implements IPersistentSet, Collection, Set, Serializable, IHashEq {
21 | int _hash = -1;
22 | int _hasheq = -1;
23 | final IPersistentMap impl;
24 |
25 | protected APersistentSet(IPersistentMap impl){
26 | this.impl = impl;
27 | }
28 |
29 | public String toString(){
30 | return RT.printString(this);
31 | }
32 |
33 | public boolean contains(Object key){
34 | return impl.containsKey(key);
35 | }
36 |
37 | public Boolean get(T key){
38 | return (Boolean) impl.valAt(key);
39 | }
40 |
41 | public int count(){
42 | return impl.count();
43 | }
44 |
45 | public ISeq seq(){
46 | return RT.keys(impl);
47 | }
48 |
49 | public Object invoke(Object arg1) {
50 | return get((T) arg1);
51 | }
52 |
53 | public boolean equals(Object obj){
54 | if(this == obj) return true;
55 | if(!(obj instanceof Set))
56 | return false;
57 | Set m = (Set) obj;
58 |
59 | if(m.size() != count())
60 | return false;
61 |
62 | for(Object aM : m)
63 | {
64 | if(!contains(aM))
65 | return false;
66 | }
67 |
68 | return true;
69 | }
70 |
71 | public boolean equiv(Object o){
72 | return equals(o);
73 | }
74 |
75 | public int hashCode(){
76 | if(_hash == -1)
77 | {
78 | //int hash = count();
79 | int hash = 0;
80 | for(ISeq s = seq(); s != null; s = s.next())
81 | {
82 | Object e = s.first();
83 | // hash = Util.hashCombine(hash, Util.hash(e));
84 | hash += Util.hash(e);
85 | }
86 | this._hash = hash;
87 | }
88 | return _hash;
89 | }
90 |
91 | public int hasheq(){
92 | if(_hasheq == -1){
93 | int hash = 0;
94 | for(ISeq s = seq(); s != null; s = s.next())
95 | {
96 | Object e = s.first();
97 | hash += Util.hasheq(e);
98 | }
99 | this._hasheq = hash;
100 | }
101 | return _hasheq;
102 | }
103 |
104 | public Object[] toArray(){
105 | return RT.seqToArray(seq());
106 | }
107 |
108 | public boolean add(Object o){
109 | throw new UnsupportedOperationException();
110 | }
111 |
112 | public boolean remove(Object o){
113 | throw new UnsupportedOperationException();
114 | }
115 |
116 | public boolean addAll(Collection c){
117 | throw new UnsupportedOperationException();
118 | }
119 |
120 | public void clear(){
121 | throw new UnsupportedOperationException();
122 | }
123 |
124 | public boolean retainAll(Collection c){
125 | throw new UnsupportedOperationException();
126 | }
127 |
128 | public boolean removeAll(Collection c){
129 | throw new UnsupportedOperationException();
130 | }
131 |
132 | public boolean containsAll(Collection c){
133 | for(Object o : c)
134 | {
135 | if(!contains(o))
136 | return false;
137 | }
138 | return true;
139 | }
140 |
141 | public Object[] toArray(Object[] a){
142 | return RT.seqToPassedArray(seq(), a);
143 | }
144 |
145 | public int size(){
146 | return count();
147 | }
148 |
149 | public boolean isEmpty(){
150 | return count() == 0;
151 | }
152 |
153 | public Iterator iterator(){
154 | return new SeqIterator(seq());
155 | }
156 |
157 | }
158 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_lang/APersistentTrie.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Rich Hickey. All rights reserved.
3 | * The use and distribution terms for this software are covered by the
4 | * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5 | * which can be found in the file epl-v10.html at the root of this distribution.
6 | * By using this software in any fashion, you are agreeing to be bound by
7 | * the terms of this license.
8 | * You must not remove this notice, or any other, from this software.
9 | **/
10 |
11 | /* rich Mar 3, 2008 */
12 |
13 | package com.github.krukow.clj_lang;
14 |
15 | import java.io.Serializable;
16 | import java.util.Collection;
17 | import java.util.Iterator;
18 | import java.util.Map;
19 | import java.util.Set;
20 |
21 | @SuppressWarnings({ "rawtypes", "serial" })
22 | public abstract class APersistentTrie extends AFn implements IPersistentTrie,
23 | IPersistentSet, Collection>, Set>, Serializable {
24 | int _hash = -1;
25 |
26 | public Object invoke(Object arg1) {
27 | return get((String) arg1);
28 | }
29 |
30 | public boolean equals(Object obj){
31 | if(this == obj) return true;
32 | if(!(obj instanceof Set))
33 | return false;
34 | Set m = (Set) obj;
35 |
36 | if(m.size() != count() || m.hashCode() != hashCode())
37 | return false;
38 |
39 | for(Object aM : m)
40 | {
41 | if(!contains(aM))
42 | return false;
43 | }
44 | // for(ISeq s = seq(); s != null; s = s.rest())
45 | // {
46 | // if(!m.contains(s.first()))
47 | // return false;
48 | // }
49 |
50 | return true;
51 | }
52 |
53 | public boolean equiv(Object o){
54 | return equals(o);
55 | }
56 |
57 | public int hashCode(){
58 | if(_hash == -1)
59 | {
60 | int hash = 0;
61 | for(ISeq s = seq(); s != null; s = s.next())
62 | {
63 | Object e = s.first();
64 | hash += Util.hash(e);
65 | }
66 | this._hash = hash;
67 | }
68 | return _hash;
69 | }
70 |
71 | public Object[] toArray(){
72 | return RT.seqToArray(seq());
73 | }
74 |
75 | public Object[] toArray(Object[] a){
76 | if(a.length >= count())
77 | {
78 | ISeq s = seq();
79 | for(int i = 0; s != null; ++i, s = s.next())
80 | {
81 | a[i] = s.first();
82 | }
83 | if(a.length > count())
84 | a[count()] = null;
85 | return a;
86 | }
87 | else
88 | return toArray();
89 | }
90 |
91 | public int size(){
92 | return count();
93 | }
94 |
95 | public boolean isEmpty(){
96 | return count() == 0;
97 | }
98 |
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/src/main/java/com/github/krukow/clj_lang/ASeq.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Rich Hickey. All rights reserved.
3 | * The use and distribution terms for this software are covered by the
4 | * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
5 | * which can be found in the file epl-v10.html at the root of this distribution.
6 | * By using this software in any fashion, you are agreeing to be bound by
7 | * the terms of this license.
8 | * You must not remove this notice, or any other, from this software.
9 | **/
10 |
11 | package com.github.krukow.clj_lang;
12 |
13 | import java.io.Serializable;
14 | import java.util.*;
15 |
16 | public abstract class ASeq extends Obj implements ISeq, Sequential, List, Serializable, IHashEq {
17 | transient int _hash = -1;
18 | transient int _hasheq = -1;
19 |
20 | public String toString(){
21 | return RT.printString(this);
22 | }
23 |
24 | @Override
25 | public IPersistentCollection empty() {
26 | return PersistentList.emptyList();
27 | }
28 |
29 |
30 | protected ASeq(IPersistentMap meta){
31 | super(meta);
32 | }
33 |
34 |
35 | protected ASeq(){
36 | }
37 |
38 | public boolean equiv(Object obj){
39 |
40 | if(!(obj instanceof Sequential || obj instanceof List))
41 | return false;
42 | ISeq ms = RT.seq(obj);
43 | for(ISeq s = seq(); s != null; s = s.next(), ms = ms.next())
44 | {
45 | if(ms == null || !Util.equiv(s.first(), ms.first()))
46 | return false;
47 | }
48 | return ms == null;
49 |
50 | }
51 |
52 | public boolean equals(Object obj){
53 | if(this == obj) return true;
54 | if(!(obj instanceof Sequential || obj instanceof List))
55 | return false;
56 | ISeq ms = RT.seq(obj);
57 | for(ISeq s = seq(); s != null; s = s.next(), ms = ms.next())
58 | {
59 | if(ms == null || !Util.equals(s.first(), ms.first()))
60 | return false;
61 | }
62 | return ms == null;
63 |
64 | }
65 |
66 | public int hashCode(){
67 | if(_hash == -1)
68 | {
69 | int hash = 1;
70 | for(ISeq s = seq(); s != null; s = s.next())
71 | {
72 | hash = 31 * hash + (s.first() == null ? 0 : s.first().hashCode());
73 | }
74 | this._hash = hash;
75 | }
76 | return _hash;
77 | }
78 |
79 | public int hasheq(){
80 | if(_hasheq == -1)
81 | {
82 | int hash = 1;
83 | for(ISeq s = seq(); s != null; s = s.next())
84 | {
85 | hash = 31 * hash + Util.hasheq(s.first());
86 | }
87 | this._hasheq = hash;
88 | }
89 | return _hasheq;
90 | }
91 |
92 | //public Object reduce(IFn f) {
93 | // Object ret = first();
94 | // for(ISeq s = rest(); s != null; s = s.rest())
95 | // ret = f.invoke(ret, s.first());
96 | // return ret;
97 | //}
98 | //
99 | //public Object reduce(IFn f, Object start) {
100 | // Object ret = f.invoke(start, first());
101 | // for(ISeq s = rest(); s != null; s = s.rest())
102 | // ret = f.invoke(ret, s.first());
103 | // return ret;
104 | //}
105 |
106 | //public Object peek(){
107 | // return first();
108 | //}
109 | //
110 | //public IPersistentList pop(){
111 | // return rest();
112 | //}
113 |
114 | public int count(){
115 | int i = 1;
116 | for(ISeq s = next(); s != null; s = s.next(), i++)
117 | if(s instanceof Counted)
118 | return i + s.count();
119 | return i;
120 | }
121 |
122 | final public ISeq seq(){
123 | return this;
124 | }
125 |
126 | public ISeq cons(T o){
127 | return new Cons(o, this);
128 | }
129 |
130 | public ISeq more(){
131 | ISeq