diff --git a/README.md b/README.md
index f00d7a1d2..083747133 100644
--- a/README.md
+++ b/README.md
@@ -34,10 +34,8 @@ applications. Notably trading, financial market applications.
- Replication *without logs*, with constant footprint cost, guarantees progress even if the network
doesn't sustain write rates.
-Chronicle Map has two meanings: [the language-agnostic data structure](
-https://github.com/OpenHFT/Chronicle-Map/tree/master/spec) and [the implementation of this data
-structure for the JVM](https://github.com/OpenHFT/Chronicle-Map/tree/master/src). Currently, this is
-the only implementation.
+Chronicle Map has two meanings: [the language-agnostic data structure](spec) and [the
+implementation of this data structure for the JVM](src). Currently, this is the only implementation.
**From Java perspective,** Chronicle Map is a `ConcurrentMap` implementation which stores the
entries *off-heap*, serializing/deserializing key and value objects to/from off-heap memory
@@ -74,8 +72,7 @@ queries*.
is a big chunk of shared memory (optionally mapped to disk), split into independent segments, each
segment has an independent memory allocation for storing the entries, a hash table for search, and a
lock in shared memory (implemented via CAS loops) for managing concurrent access. Read [the
-Chronicle Map design overview](
-https://github.com/OpenHFT/Chronicle-Map/blob/master/spec/2-design-overview.md) for more.
+Chronicle Map design overview](spec/2-design-overview.md) for more.
### Chronicle Map is *not*
@@ -132,7 +129,7 @@ Not supported out of the box in open-source version, but could be added in ad-ho
### Difference between Chronicle Map 2 and 3
-Changes in Chronicle Map 3:
+Functional changes in Chronicle Map 3:
- Added support for multi-key queries.
- "Listeners" mechanism fully reworked, see the [Behaviour Customization](#behaviour-customization)
@@ -148,9 +145,15 @@ Changes in Chronicle Map 3:
[Number of entries configuration](#number-of-entries-configuration) section.
- A number of smaller improvements and fixes.
+Non-functional changes:
+
+ - Chronicle Map 3 requires Java version 8 or newer, while Chronicle Map 2 supports Java 7.
+ - Chronicle Map 3 has [specification](spec), [versioning policy](docs/versioning.md) and
+ [compatibility policy](docs/compatibility.md). Chronicle Map 2 doesn't have such documents.
+
If you use Chronicle Map 2, you might be looking for [Chronicle Map 2 Tutorial](
https://github.com/OpenHFT/Chronicle-Map/tree/2.1#contents) or [Chronicle Map 2 Javadoc](
-http://openhft.github.io/Chronicle-Map/apidocs/).
+http://www.javadoc.io/doc/net.openhft/chronicle-map/2.3.9/).
### Download the library
@@ -167,11 +170,8 @@ http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22net.openhft%22%20AND%20a%3A%22
#### Maven Snapshot Download
If you want to try out the latest pre-release code, you can download the snapshot artifact manually
-from:
-```xml
-https://oss.sonatype.org/content/repositories/snapshots/net/openhft/chronicle-map/
-```
-a better way is to add the following to your setting.xml, to allow maven to download snapshots:
+from https://oss.sonatype.org/content/repositories/snapshots/net/openhft/chronicle-map/.
+A better way is to add the following to your `setting.xml`, to allow maven to download snapshots:
```xml
@@ -765,17 +765,17 @@ is not required.
Each map is allocated a unique identifier
Server 1 has:
-```
+```java
.replication((byte) 1, tcpConfigServer1)
```
Server 2 has:
-```
+```java
.replication((byte) 2, tcpConfigServer2)
```
Server 3 has:
-```
+```java
.replication((byte) 3, tcpConfigServer3)
```
@@ -791,12 +791,12 @@ other map is connected to. So currently, if you had 4 servers each with a Chroni
require 6 connections.
In our case we are only using 2 maps, this is how we connected map1 to map 2.
-```
+```java
TcpTransportAndNetworkConfig.of(8076, new InetSocketAddress("localhost", 8077))
.heartBeatInterval(1, SECONDS);
```
you could have put this instruction on map2 instead, like this
-```
+```java
TcpTransportAndNetworkConfig.of(8077, new InetSocketAddress("localhost", 8076))
.heartBeatInterval(1, SECONDS);
```
@@ -865,7 +865,7 @@ update. Put simply:
* Each host must be given a unique identifier.
* Each map must be given a unique channel.
-``` java
+```java
byte identifier= 2;
ReplicationHub replicationHub = ReplicationHub.builder()
.tcpTransportAndNetwork(tcpConfig)
@@ -878,7 +878,7 @@ With channels you are able to attach additional maps to a `ReplicationChannel` o
running.
When creating the `ReplicationChannel` you should attach your tcp or udp configuration :
-``` java
+```java
byte identifier = 1;
ReplicationHub replicationHub = ReplicationHub.builder()
.tcpTransportAndNetwork(tcpConfig)
@@ -887,7 +887,7 @@ ReplicationHub replicationHub = ReplicationHub.builder()
Attaching a `ReplicationChannel` to the map :
-``` java
+```java
short channel = (short) 2;
ChronicleMap map = ChronicleMap
.of(IntValue.class, CharSequence.class)
@@ -913,7 +913,7 @@ unique for each map you have.
#### Channels and ReplicationChannel - Example
-``` java
+```java
import net.openhft.chronicle.hash.replication.ReplicationChannel;
import net.openhft.chronicle.hash.replication.ReplicationHub;
@@ -1061,7 +1061,7 @@ Combined, interception SPI interfaces and `ChronicleMap.queryContext()` API are
Just log all modification operations on `ChronicleMap`
-```
+```java
class SimpleLoggingMapEntryOperations implements MapEntryOperations {
private static final SimpleLoggingMapEntryOperations INSTANCE =
@@ -1098,7 +1098,7 @@ class SimpleLoggingMapEntryOperations implements MapEntryOperations map = ChronicleMap
.of(Integer.class, IntValue.class)
.entries(100)
@@ -1113,11 +1113,11 @@ ChronicleMap map = ChronicleMap
Possible bidirectional map (i. e. a map that preserves the uniqueness of its values as well
as that of its keys) implementation over Chronicle Maps.
-```
+```java
enum DualLockSuccess {SUCCESS, FAIL}
```
-```
+```java
class BiMapMethods implements MapMethods {
@Override
public void remove(MapQueryContext q, ReturnValue returnValue) {
@@ -1240,7 +1240,7 @@ class BiMapMethods implements MapMethods {
}
```
-```
+```java
class BiMapEntryOperations implements MapEntryOperations {
ChronicleMap reverse;
@@ -1302,7 +1302,7 @@ class BiMapEntryOperations implements MapEntryOperations biMapOps1 = new BiMapEntryOperations<>();
ChronicleMap map1 = ChronicleMapBuilder
.of(Integer.class, CharSequence.class)
@@ -1335,7 +1335,7 @@ System.out.println(map2.get("1"));
`Set` values won't replace each other on replication, but will converge to a single, common set,
the union of all elements added to all sets on all replicated nodes.
-```
+```java
class GrowOnlySetValuedMapEntryOperations
implements MapEntryOperations, Void> {
@@ -1357,7 +1357,7 @@ class GrowOnlySetValuedMapEntryOperations
}
```
-```
+```java
class GrowOnlySetValuedMapRemoteOperations
implements MapRemoteOperations, Void> {
@@ -1392,7 +1392,7 @@ class GrowOnlySetValuedMapRemoteOperations
```
Usage:
-```
+```java
HashSet averageValue = new HashSet<>();
for (int i = 0; i < AVERAGE_SET_SIZE; i++) {
averageValue.add(i);
diff --git a/docs/compatibility.md b/docs/compatibility.md
new file mode 100644
index 000000000..bda15a73c
--- /dev/null
+++ b/docs/compatibility.md
@@ -0,0 +1,62 @@
+# Chronicle Map 3 Compatibility
+
+## Java implementation compatibility
+
+### Public API
+
+For Chronicle Map, *public API* is comprised of public classes that are included in [Javadoc](
+http://www.javadoc.io/doc/net.openhft/chronicle-map/). Other public classes are not subject for
+the following rules, they might be changed in any way, or removed.
+
+ - Class and method names, types and number of parameters in already existing methods shouldn't be
+ changed.
+ - Any methods could be added to the classes and interfaces that are not subject for
+ subclassing or implementing by the library users, such as `ChronicleMap`, `ChronicleMapBuilder`,
+ `MapEntry`, but in a way that any existing code calling methods on those classes still compile, not
+ break due to ambiguity in method resolution.
+ - Only non-abstract (concrete or default) methods could be added to the classes and interfaces that
+ are subject for subclassing by the library users, such as `MapMethods`, `MapEntryOperations`,
+ `SizedReader`, `TimeProvider`.
+
+### Behaviour
+
+Semantics and actual effects of API calls might change between Chronicle Map versions with
+[different "minor" number](versioning.md), e. g. default serialization forms of key or value objects
+of some types could change, "high level" configurations in `ChronicleMapBuilder` could produce
+Chronicle Map instances with different properties, etc. Such changes should be documented in release
+notes.
+
+### Persistence file binary form
+
+A persisted Chronicle Map instance (a binary file), produced by a production release of the library,
+should be accessible and updatable by any subsequent production release of the library in 3.x
+branch, unless the older version has bugs that lead to data corruption.
+
+To support this,
+ - Serialization forms of any classes should be changed. When e. g. a marshaller class (say,
+ `StringBytesReader`) of object of some type is changed, and it's serialization form should be
+ changed, a new class called `StringBytesReader_3_5` (5 is the "minor" number of the version of the
+ library, in which this change is made) should be created and put along with older class.
+ - When the specification revision is updated (hence binary form could be completely changed), a
+ new version of root implementation class, e. g. `VanillaChronicleMap_3_5` should be created and
+ put along with older version, which should keep behave the same as before.
+
+### Replication protocol
+
+The replication protocol might change between Chronicle Map versions with different "minor" number.
+Chronicle Map nodes running different versions of the library shouldn't communicate to each other.
+Though this might lead to failures, but not to data corruption on either of the nodes.
+
+## Specification compatibility
+
+Chronicle Map Data Structure Specification could be updated without revision change while it remains
+backward compatible, i. e. implementation of the newer version of specification could access and
+update any persisted Chronicle Map instance, produced by older version. In addition, potential
+*concurrent* accessing implementations of older versions ("within" the same revision) shouldn't lose
+correctness and corrupt the data.
+
+If more substantial changes to the specification are required, the revision number should be
+updated.
+
+The binary form of Chronicle Map and algorithms could change between revisions to any degree, but
+[guarantees](../spec/1-design-goals.md) provided by the specification shouldn't be weaken.
\ No newline at end of file
diff --git a/docs/versioning.md b/docs/versioning.md
new file mode 100644
index 000000000..0766725e8
--- /dev/null
+++ b/docs/versioning.md
@@ -0,0 +1,49 @@
+# Chronicle Map 3 Versioning
+
+## Java implementation versioning
+
+3.minor.patch
+
+"Minor" number should be updated, when
+
+ - A feature, or public API method is added.
+ - Behaviour of `ChronicleMap`, `ChronicleMapBuilder` or any other class or method or subsystem
+ is semantically changed.
+ - For example, when configuration heuristics in `ChronicleMapBuilder` are improved, and
+ `ChronicleMapBuilder` configured the same way constructs a `ChronicleMap` with different
+ number of segments, or segment's capacity, etc.
+ - Any dependency is updated, even if only "patch" number is updated, e. g. `chronicle-bytes`
+ dependency is updated from `1.1.1` to `1.1.2`.
+ - Bug fixing, performance optimization or feature addition requires to change binary or serialized
+ form of the Chronicle Map data structure (therefore revise the Chronicle Map Specification, see
+ below), or binary replication protocol, or serialization form of some marshaller classes, that
+ requires to [create new versions of classes](compatibility.md).
+
+"Minor" number shouldn't be updated, i. e. the next release could update only the "patch" number,
+when
+
+ - A bug fixed, in a way that doesn't make any working code to change it's behaviour semantically.
+ - Performance optimized: some working code changes it's performance characteristics,
+ but not semantics
+
+During development after the release of the version `3.y.z` the library should be versioned
+`3.y.-SNAPSHOT`. As soon as changes made are substantial enough for the next released version
+to update the "minor" number, the version should be changed to `3..0-SNAPSHOT`, *in the same
+commit* these changes are made.
+
+Suffixes `-alpha`, `-beta`, `-rc` etc. mean this is a pre-production release.
+
+## Specification versioning
+
+The first Chronicle Map 3 production release designates the Chronicle Map Specification revision 1.
+
+When the specification should be updated in a way that is not [backward compatible](
+compatibility.md#specification-compatibility), the revision should be updated (revision 2, 3, ...)
+and the Java implementation of this revision should have "minor" number updated in it's version.
+
+During development after the release of the revision `x`, while the specification is backward
+compatible, it should remain versioned `x`. In the same commit where specification becomes
+incompatible, it's revision should be set to `-pre` until the next production release.
+
+Releases and updates to the "minor" number in the library version should be synchronized with
+updates to the specification revision number.
diff --git a/pom.xml b/pom.xml
index 7dc69d295..462c324b9 100755
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
4.0.0
chronicle-map
- 3.2.1-beta-SNAPSHOT
+ 3.3.0-beta-SNAPSHOT
OpenHFT/Chronicle-Map
Chronicle-Map
bundle
diff --git a/spec/README.md b/spec/README.md
index 8b4aeed0b..9267e1d81 100644
--- a/spec/README.md
+++ b/spec/README.md
@@ -1,6 +1,6 @@
-# Chronicle Map specification
+# The Chronicle Map Specification, revision 1-pre
-This directory contains the Chronicle Map specification.
+This directory contains the Chronicle Map Specification.
This is currently work-in-progress.