Skip to content

v0.16

Compare
Choose a tag to compare
@simerplaha simerplaha released this 20 Sep 11:37
· 588 commits to master since this release

This release was focused on

  • MultiMap & Compaction performance improvements.
  • Completing Java API.
  • QA and Usability testing.
  • Support for Boopickle serialisation.
  • Resolving issues labeled Production release.

MultiMap and SetMap Java types

MultiMap and SetMap are now implemented for Java. Java API is now complete.

MultiMap allows creating deeply nested Map.

//create a root map
MultiMap<String, Integer, String, Void> root =
  MemoryMultiMap.functionsOff(
    stringSerializer(), //nested Map key type
    intSerializer(), //key type
    stringSerializer() //value type
  ).get();

//first child map
MultiMap<String, Integer, String, Void> child1 = root.child("first child");
child1.put(1, "child1's value 1");

SetMap provides Map like API for Set. Useful for application that always fetch the value with the key. It stores both key & value in the same location for faster seeks and reduced IOps.

SetMap<Integer, String> setMap =
  MemorySetMap
    .config(intSerializer(), stringSerializer())
    .get();

setMap.put(1, "one");

Improved MultiMap performance and reduced storage cost

MultiMap previously stored parent key bytes within child key bytes. Now deeply nested Map do not have any extra storage cost over a root MultiMap. This also improved read and write performance.

Deeply nested MultiMap has constant performance regardless of the depth.

Access to all nested child MultiMap nodes

//get all children of root map
Stream<MultiMap<String, Integer, String, Void>> children = root.children();
//get all children of root map and all it's grand children. 
Stream<MultiMap<String, Integer, String, Void>> child = root.childrenFlatten();

Functions

Shorter syntax for enabling functions

Java

Create functions without need to specify the return type. All java functions types are under PureFunctionJava.

//function that appends "updated" to old value
OnValue<Integer, String> myFunction =
  (String value) ->
    Apply.update(value + " updated");

Register the function as a List.

Map<Integer, String, PureFunction<Integer, String, Apply.Map<String>>> map =
  PersistentMap
    .functionsOn(
      Paths.get("my_map"), //directory
      Default.intSerializer(), //key serialiser
      Default.stringSerializer(), //value serializwr
      Arrays.asList(myFunction) //functions list
    ).get();

Scala

Syntax shortened for enabling functions - PureFunction.Map[Int, String]. All Scala function types are under PureFunctionScala.

val map = persistent.Map[Int, String, PureFunction.Map[Int, String], Bag.Less]("my_map")

To register function supply implicit functions List.

//sample function that appends "updated" to old value
val myFunction: OnValue[String] = (value: String) => Apply.Update(value + " updated")

implicit val myFunctions = Functions[PureFunction.Map[Int, String]](myFunction)

Added new function types

  • OnKey - reads the key
  • OnKeyDeadline (Scala) & OnKeyExpiration (Java) - reads the key and deadline
  • OnKeyValue - reads the key and value
  • OnValue - reads the value
  • OnValueDeadline (Scala) & OnValueExpiration (Java) - reads the value and deadline
  • OnKeyValueValueDeadline (Scala) & OnKeyValueValueExpiration (Java) - read the key, value and deadline.

Improve Serialisers

Java

Use Slice<T> to easily build custom serialisers. ByteOps.Java removes the need to cast java.lang.Byte to scala.Byte during runtime.

new Serializer<String>() {
  @Override
  public Slice<Byte> write(String data) {
    return Slice.writeStringUTF8(data, ByteOps.Java());
  }

  @Override
  public String read(Slice<Byte> slice) {
    return slice.readStringUTF8(ByteOps.Java());
  }
};

Scala

Easily serialise case classes using Bookpickle

import swaydb._
import boopickle.Default._

case class MyClass(id: Int, value: String)

implicit val serialiser = swaydb.serializers.BooPickle[MyClass]

val set = memory.Set[MyClass, Nothing, Bag.Less]()

Better Scala and Java interop

Scala functions can be shared with Java and vice versa. Scala instance can also be accessed from Java.

Set<Integer, Void> mySet =
  MemorySet
    .functionsOff(intSerializer())
    .get();

mySet.asScala(); //get scala set

Validating missing functions

Missing applied functions reported on re-boot to ensure safe startups.

swaydb.Exception$MissingFunctions: Missing 1 function. List("myFunction").

Flags for clearing applied functions

Functions that are applied can be cleared by setting the clearAppliedFunctionsOnBoot flag.

Scala

val map = persistent.Set[Int, PureFunction.Set[Int], Bag.Less]("my_set", clearAppliedFunctionsOnBoot = true)

Java

Set<Integer, PureFunction<Integer, Void, Apply.Set<Void>>> mySet =
  PersistentSet
    .functionsOn(Paths.get("my_set"), intSerializer(), Arrays.asList())
    .setClearAppliedFunctionsOnBoot(true)
    .get();

Build Validator - Error reporting

Incompatible SwayDB version files get reported on boot-up.

Eg: Current v0.16 is incompatible with older versions so start v0.16 on older versions will result in the following error

Incompatible versions! SwayDB v0.16 is not compatible with files created by v0.15

Directories are type-checked. Eg: starting Set on a Map directory will yield

Invalid data type Set for the directory of type Map.