Functional Map API with Embedded Infinispan

What You Will Learn

How to use the Infinispan functional map API, which provides a lambda-based approach to cache operations with write-only, read-only, and read-write map views.

Prerequisites

  • Java 17+

Step 1: Add the Embedded Dependency

Add Infinispan core to your pom.xml:

<dependency>
   <groupId>org.infinispan</groupId>
   <artifactId>infinispan-core</artifactId>
</dependency>

Step 2: Create the Functional Map

Obtain a FunctionalMapImpl from an AdvancedCache, then create typed map views:

      cacheManager = new DefaultCacheManager();
      cacheManager.defineConfiguration("local", new ConfigurationBuilder().build());
      cache = cacheManager.<String, String>getCache("local").getAdvancedCache();
      functionalMap = FunctionalMapImpl.create(cache);
      writeOnlyMap = WriteOnlyMapImpl.create(functionalMap);
      readOnlyMap = ReadOnlyMapImpl.create(functionalMap);

Step 3: Write and Read Entries

Use write-only operations to store values and chain read-only operations with CompletableFuture:

      // Execute two parallel write-only operation to store key/value pairs
      CompletableFuture<Void> writeFuture1 = writeOnlyMap.eval("key1", "value1",
         (v, writeView) -> writeView.set(v));
      CompletableFuture<Void> writeFuture2 = writeOnlyMap.eval("key2", "value2",
         (v, writeView) -> writeView.set(v));

      // When each write-only operation completes, execute a read-only operation to retrieve the value
      CompletableFuture<String> readFuture1 =
         writeFuture1.thenCompose(r -> readOnlyMap.eval("key1", EntryView.ReadEntryView::get));
      CompletableFuture<String> readFuture2 =
         writeFuture2.thenCompose(r -> readOnlyMap.eval("key2", EntryView.ReadEntryView::get));

      // When the read-only operation completes, print it out
      System.out.printf("Created entries: %n");
      CompletableFuture<Void> end = readFuture1.thenAcceptBoth(readFuture2, (v1, v2) ->
         System.out.printf("key1 = %s%nkey2 = %s%n", v1, v2));

      // Wait for this read/write combination to finish
      end.get();

Step 4: Use Read-Write Operations

The read-write map supports atomic operations that read the previous value and write a new one, with optional metadata like lifespan:

      // Create a read-write map
      FunctionalMap.ReadWriteMap<String, String> readWriteMap = ReadWriteMapImpl.create(functionalMap);

      // Use read-write multi-key based operation to write new values
      // together with lifespan and return previous values
      Map<String, String> data = new HashMap<>();
      data.put("key1", "newValue1");
      data.put("key2", "newValue2");
      Traversable<String> previousValues = readWriteMap.evalMany(data, (v, readWriteView) -> {
         String prev = readWriteView.find().orElse(null);
         readWriteView.set(v, new MetaLifespan(Duration.ofHours(1).toMillis()));
         return prev;
      });

Step 5: Run the Tutorial

mvn package exec:java

The output shows created entries, updated entries with their new values, and the previous values before the update.

What’s Next