Skip to content

Commit

Permalink
mark 0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ztellman committed Nov 4, 2018
1 parent 29cb1ef commit 2b28aa1
Show file tree
Hide file tree
Showing 14 changed files with 109 additions and 162 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<dependency>
<groupId>io.lacuna</groupId>
<artifactId>bifurcan</artifactId>
<version>0.1.0-alpha6</version>
<version>0.1.0</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion doc/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ The two mutable collections are significantly faster, while for smaller collecti

Unlike Java's `HashMap` and `HashSet`, Bifurcan's `LinearMap` and `LinearSet` store their entries contiguously, which makes both iteration and cloning significantly faster.

Bifurcan, Capsule, and Scala are all comparable to Java's `HashMap`, while the others are constant factor slower.
Bifurcan, Capsule, and Scala are all comparable to Java's `HashMap`, while the others are a constant factor slower.

---

Expand Down
3 changes: 2 additions & 1 deletion project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
(cemerick.pomegranate.aether/register-wagon-factory!
"http" #(org.apache.maven.wagon.providers.http.HttpWagon.))

(defproject io.lacuna/bifurcan "0.1.0-alpha6"
(defproject io.lacuna/bifurcan "0.1.0"
:java-source-paths ["src"]
:dependencies []
:test-selectors {:default #(not
Expand Down Expand Up @@ -38,6 +38,7 @@
"-XX:+UseG1GC"
"-XX:-OmitStackTraceInFastThrow"
"-ea:io.lacuna..."
"-Xmx4g"

#_"-XX:+UnlockDiagnosticVMOptions"
#_"-XX:+PrintAssembly"
Expand Down
6 changes: 1 addition & 5 deletions src/io/lacuna/bifurcan/Graphs.java
Original file line number Diff line number Diff line change
Expand Up @@ -226,19 +226,15 @@ public static <V, E> Optional<IList<V>> shortestPath(IGraph<V, E> graph, Iterabl
/// undirected graphs

public static <V> Set<Set<V>> connectedComponents(IGraph<V, ?> graph) {
if (graph.isDirected()) {
throw new IllegalArgumentException("graph must be undirected, try Graphs.stronglyConnectedComponents instead");
}

LinearSet<V> traversed = new LinearSet<>((int) graph.vertices().size(), graph.vertexHash(), graph.vertexEquality());
Set<Set<V>> result = new Set<Set<V>>().linear();

for (V seed : graph.vertices()) {
if (!traversed.contains(seed)) {
traversed.add(seed);
Set<V> group = new Set<>(graph.vertexHash(), graph.vertexEquality()).linear();
bfsVertices(LinearList.of(seed), graph::out).forEach(group::add);
result.add(group.forked());
group.forEach(traversed::add);
}
}

Expand Down
78 changes: 78 additions & 0 deletions src/io/lacuna/bifurcan/ICollection.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package io.lacuna.bifurcan;

/**
* @author ztellman
*/
public interface ICollection<C, V> extends Iterable<V> {

/**
* This returns a data structure which is <i>linear</i>, which is equivalent to Clojure's <i>transient</i>
* data structures: only the most recent reference to the data structure should be used. If a linear data structure
* is modified (for instance, calling {@code addLast()} on an {@code IList}), we should only refer to the object returned
* by that method; anything else has undefined results.
* <p>
* The term "linear", as used here, does not completely align with the formal definition of <a href="https://en.wikipedia.org/wiki/Substructural_type_system#Linear_type_systems">linear types</a>
* as used in type theory. It is meant to describe the linear dataflow of the method calls, and as a converse to
* "forked" data structures.
* <p>
* If the data structure is already linear, it will simply return itself.
*
* @return a linear form of this data structure
*/
C linear();

/**
*
* @return true, if the collection is linear
*/
boolean isLinear();

/**
* This returns a data structure which is <i>forked</i>, which is equivalent to Clojure's <i>persistent</i>
* data structures, also sometimes called <i>functional</i> or <i>immutable</i>. This is called "forked" because it
* means that multiple functions can make divergent changes to the data structure without affecting each other.
* <p>
* If only a single function or scope uses the data structure, it can be left as a <i>linear</i> data structure, which
* can have significant performance benefits.
* <p>
* If the data structure is already forked, it will simply return itself.
*
* @return a forked form of the data structure
*/
C forked();

/**
* Splits the collection into roughly even pieces, for parallel processing. Depending on the size and contents of
* the collection, this function may not return exactly {@code parts} subsets.
*
* @param parts the target number of pieces
* @return a list containing subsets of the collection.
*/
IList<? extends C> split(int parts);

/**
* @return the number of elements in the collection
*/
long size();

/**
* @return the element at {@code idx}
* @throws IndexOutOfBoundsException when {@code idx} is not within {@code [0, size-1]}
*/
V nth(long idx);

/**
* @return the element at {@code idx}, or {@code defaultValue} if it is not within {@code [0, size-1]}
*/
default V nth(long idx, V defaultValue) {
if (idx < 0 || idx >= size()) {
return defaultValue;
}
return nth(idx);
}

/**
* @return a cloned copy of the collection
*/
C clone();
}
20 changes: 0 additions & 20 deletions src/io/lacuna/bifurcan/IForkable.java

This file was deleted.

30 changes: 19 additions & 11 deletions src/io/lacuna/bifurcan/IGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/**
* @author ztellman
*/
public interface IGraph<V, E> extends ILinearizable<IGraph<V, E>>, IForkable<IGraph<V, E>> {
public interface IGraph<V, E> extends ICollection<IGraph<V, E>, V> {

/**
* @return the set of all vertices in the graph
Expand Down Expand Up @@ -79,6 +79,14 @@ default V nth(long index) {
return vertices().nth(index);
}

default Iterator<V> iterator() {
return vertices().iterator();
}

default long size() {
return vertices().size();
}

/**
* @return a graph containing only the specified vertices and the edges between them
*/
Expand Down Expand Up @@ -116,31 +124,31 @@ default IGraph<V, E> replace(V a, V b, BinaryOperator<E> merge) {
}

/**
* @return
*/
boolean isLinear();

/**
* @return
* @return whether the graph is directed
*/
boolean isDirected();

/**
* @return
* @return the hash function for vertices
*/
ToIntFunction<V> vertexHash();

/**
* @return
* @return the equality check for vertices
*/
BiPredicate<V, V> vertexEquality();

/**
* @return
* @return a transposed version of the graph
*/
IGraph<V, E> transpose();

IGraph<V, E> clone();
/**
* @return a singleton list of the graph, unsplit. The graph can be split into separate pieces in linear time using {@code Graphs.connectedComponents()}.
*/
default IList<? extends IGraph<V, E>> split(int parts) {
return List.of(this);
}

// polymorphic utility methods

Expand Down
28 changes: 0 additions & 28 deletions src/io/lacuna/bifurcan/ILinearizable.java

This file was deleted.

31 changes: 2 additions & 29 deletions src/io/lacuna/bifurcan/IList.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

import io.lacuna.bifurcan.Lists.VirtualList;

import java.lang.reflect.Array;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.LongFunction;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
Expand All @@ -19,31 +17,8 @@
*/
@SuppressWarnings("unchecked")
public interface IList<V> extends
ISplittable<IList<V>>,
Iterable<V>,
IForkable<IList<V>>,
ILinearizable<IList<V>> {

/**
* @return the element at {@code idx}
* @throws IndexOutOfBoundsException when {@code idx} is not within {@code [0, size-1]}
*/
V nth(long idx);

/**
* @return the element at {@code idx}, or {@code defaultValue} if it is not within {@code [0, size-1]}
*/
default V nth(long idx, V defaultValue) {
if (idx < 0 || idx >= size()) {
return defaultValue;
}
return nth(idx);
}

/**
* @return the length of the list
*/
long size();
ICollection<IList<V>, V>,
Iterable<V> {

default IList<V> update(long idx, Function<V, V> updateFn) {
return set(idx, updateFn.apply(nth(idx)));
Expand Down Expand Up @@ -200,8 +175,6 @@ default IList<V> linear() {
return new VirtualList<V>(this).linear();
}

IList<V> clone();

default boolean equals(Object o, BiPredicate<V, V> equals) {
if (o instanceof IList) {
return Lists.equals(this, (IList<V>) o, equals);
Expand Down
17 changes: 1 addition & 16 deletions src/io/lacuna/bifurcan/IMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@
*/
@SuppressWarnings("unchecked")
public interface IMap<K, V> extends
Iterable<IEntry<K, V>>,
ISplittable<IMap<K, V>>,
ILinearizable<IMap<K, V>>,
IForkable<IMap<K, V>>,
ICollection<IMap<K, V>, IEntry<K, V>>,
Function<K, V> {

/**
Expand Down Expand Up @@ -71,11 +68,6 @@ default IList<IEntry<K, V>> entries() {
*/
long indexOf(K key);

/**
* @return the nth entry in the map
*/
IEntry<K, V> nth(long index);

/**
* @return a set representing all keys in the map
*/
Expand All @@ -90,11 +82,6 @@ default IList<V> values() {
return Lists.lazyMap(entries(), IEntry::value);
}

/**
* @return the number of entries in the map
*/
long size();

/**
* @param f a function which transforms the values
* @param <U> the new type of the values
Expand Down Expand Up @@ -270,8 +257,6 @@ default IList<? extends IMap<K, V>> split(int parts) {
.collect(Lists.collector());
}

IMap<K, V> clone();

/**
* @param m another map
* @param equals a predicate which checks value equalities
Expand Down
Loading

0 comments on commit 2b28aa1

Please sign in to comment.