You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+50-13
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@
4
4
<dependency>
5
5
<groupId>io.lacuna</groupId>
6
6
<artifactId>bifurcan</artifactId>
7
-
<version>0.2.0-alpha1</version>
7
+
<version>0.2.0-alpha4</version>
8
8
</dependency>
9
9
```
10
10
@@ -16,13 +16,14 @@ This library provides high-quality Java implementations of mutable and immutable
16
16
* customizable equality semantics
17
17
* contiguous memory used wherever possible
18
18
* performance equivalent to, or better than, existing alternatives
19
+
* changes to a collection can be tracked in a **diff** data structure, which can be subsequently rebased onto a different collection
19
20
*[ALPHA] durable (disk-backed) representations which share the API and asymptotic performance of their in-memory counterparts
20
21
21
22
Rather than using the existing collection interfaces in `java.util` such as `List` or `Map`, it provides its own interfaces (`IList`, `IMap`, `ISet`) that provide functional semantics - each update to a collection returns a reference to a new collection. Each interface provides a method (`toList`, `toMap`, `toSet`) for coercing the collection to a read-only version of the standard Java interfaces.
22
23
23
24
### what makes this better?
24
25
25
-
Some aspects of this library, like the inverted indices and durable collections, are unique.
26
+
Some aspects of this library, like the inverted indices, diffs, and durable collections, are unique.
26
27
27
28
There are, however, many existing implementations of "functional" (aka persistent, immutable) data structures on the JVM. As shown in [these in-depth comparisons](https://github.com/lacuna/bifurcan/blob/master/doc/comparison.md), Bifurcan's performance is equivalent to the best existing implementations for basic operations, and significantly better for batch operations such as `union`, `intersection`, and `difference`.
28
29
@@ -80,28 +81,64 @@ for (int i = 0; i < 1000; i++) {
80
81
}
81
82
```
82
83
83
-
If we call `forked()` on this collection, it will be wrapped in an immutable "diff" facade which tracks changes without touching the underlying collection. These facades have similar performance to typical collections, but do not support efficient set operations.
84
+
If we call `forked()` on this collection, it will be wrapped in a **diff** facade, which is described below.
84
85
85
86
### virtual collections
86
87
87
-
These facades also allow us to define collections programmatically:
88
+
Bifurcan offers a variety of collection implementations, but you can also create your own by implementing a handful of methods.
89
+
90
+
A list, at its base, is just a `size` and a function that, given an index, returns the corresponding element. This can be constructed using the `Lists.from` method:
88
91
89
92
```java
90
-
// a list of numbers within [0,1e6)
91
93
IList<Long> list =Lists.from(1_000_000, i -> i);
92
-
93
-
// the set of numbers within [0,1e6)
94
-
ISet<Long> set =Sets.from(list, i -> (0<= i && i < list.size()) ?OptionalLong.of(i) :OptionalLong.empty());
95
-
96
-
// a map of numbers within [0,1e6) onto their square
97
-
IMap<Long, Long> map =Maps.from(set, i -> i * i);
98
94
```
99
95
100
-
These collections are not realized in-memory, and can be used as a translation layer for other data structure implementations. Using our facades, however, we can still update them like any other collection, and only those changes will be directly represented in-memory.
96
+
This creates a list of the numbers within `[0, 1e6)` without any of the elements being stored in memory. All of the other operations associated with lists (adding and removing elements, updating elements, concatenating other lists, and so on) have efficient default implementations, which will be discussed in the next section.
97
+
98
+
An unsorted set is just a list of elements, plus a function that, given an value, returns an `OptionalLong` describing the index of that element:
99
+
100
+
```java
101
+
Function<Long, OptionalLong> indexOf = n -> (0<= n && n < list.size()) ?OptionalLong.of(i) :OptionalLong.empty();
102
+
103
+
ISet<Long> set =Sets.from(list, indexOf)
104
+
```
105
+
106
+
A sorted set, conversely, is a list of elements, a comparator, and a function that, given a value, returns an `OptionalLong` describing the index of the closest element which equal to or less than that value (referred to as the "floor index"):
107
+
108
+
```java
109
+
Function<Double, OptionalLong> floorIndexOf = n -> indexOf.apply((long) n);
Sorted and unsorted maps are just their corresponding sets, plus a function from key to value. These can be constructed using `Maps.from`, or by calling `zip` on a set:
These virtual collections can be modified just like any other Bifurcan collection:
123
+
124
+
```java
125
+
Lists.from(1, x ->1).addLast(42)
126
+
// [1, 42]
127
+
```
128
+
129
+
This is made possible by [diffs](https://lacuna.io/docs/bifurcan/io/lacuna/bifurcan/IDiff.html), which track changes on an immutable **underlying** collection. Diff implementations exists for all variants of Bifurcan collections, and share the asymptotic performance of their normal counterparts. By calling `diff()` on any collection, we create a diff wrapper whose changes can then be **rebased** onto a new underlying collection:
All in-memory structures can be saved to disk, while retaining the same API and asymptotic performance. These durable collections are optimized for reads and batched writes, which means they are not a replacement for general-purpose databases, but they are still [useful in a variety of applications](doc/durable.md).
141
+
All in-memory structures can be also saved to disk, while retaining the same API and asymptotic performance. These durable collections are optimized for reads and batched writes, which means they are not a replacement for general-purpose databases, but they are still [useful in a variety of applications](doc/durable.md).
0 commit comments