Skip to content

Commit

Permalink
ISPN-7780 multimap embedded first shot
Browse files Browse the repository at this point in the history
  • Loading branch information
karesti committed Jun 21, 2017
1 parent ecbe0f5 commit 8693df7
Show file tree
Hide file tree
Showing 26 changed files with 2,019 additions and 1 deletion.
1 change: 1 addition & 0 deletions core/pom.xml
Expand Up @@ -162,6 +162,7 @@
<Export-Package>
!${project.groupId}.commons.*,
!${project.groupId}.counter.*,
!${project.groupId}.multimap.*,
org.infinispan.marshall.core,
${project.groupId}.*;version=${project.version};-split-package:=error
</Export-Package>
Expand Down
Expand Up @@ -54,6 +54,10 @@ public class ClusterExpirationManager<K, V> extends ExpirationManagerImpl<K, V>
private AdvancedCache<K, V> cache;
private boolean needTransaction;

public ExecutorService getAsyncExecutor() {
return asyncExecutor;
}

@Inject
public void inject(AdvancedCache<K, V> cache, Configuration configuration,
@ComponentName(KnownComponentNames.ASYNC_OPERATIONS_EXECUTOR) ExecutorService asyncExecutor) {
Expand Down
Expand Up @@ -47,7 +47,6 @@ public static void assertIsInContainerImmortal(Cache<?, ?> cache, Object key) {
log.fatal(msg);
assert false : msg;
}

if (!(ice instanceof ImmortalCacheEntry)) {
String msg = "Entry for key [" + key + "] on cache at [" + addressOf(cache) + "] should be immortal but was [" + ice + "]!";
log.fatal(msg);
Expand Down
2 changes: 2 additions & 0 deletions documentation/src/main/asciidoc/user_guide/marshalling.adoc
Expand Up @@ -436,6 +436,8 @@ This is the list of Externalizer identifiers that are used by Infinispan based m
|Infinispan Scripting Module:|1800 - 1849
|Infinispan Server Event Logger Module:|1850 - 1899
|Infinispan Remote Store:|1900 - 1999
|Infinispan Counters:|2000 - 2049
|Infinispan Multimap:|2050 - 2099
|===============


144 changes: 144 additions & 0 deletions documentation/src/main/asciidoc/user_guide/multimapcache.adoc
@@ -0,0 +1,144 @@
== Multimap Cache

Infinispan Multimap Cache is a new distributed and clustered collection type introduced in Infinispan 9.
MutimapCache is a type of Infinispan Cache that maps keys to values in which each key can contain multiple values.

=== Installation and configuration

.pom.xml
[source,xml]
----
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-multimap</artifactId>
<version>...</version> <!-- 9.2.0.Final or higher -->
</dependency>
----

=== MultimapCache API

MultimapCache API exposes several methods to interact with the Multimap Cache.
All these methods are non-blocking in most of the cases. See [limitations]

[source,java]
----
public interface MultimapCache<K, V> {
CompletableFuture<Void> put(K key, V value);
CompletableFuture<Collection<V>> get(K key);
CompletableFuture<Boolean> remove(K key);
CompletableFuture<Boolean> remove(K key, V value);
CompletableFuture<Void> remove(Predicate<? super V> p);
CompletableFuture<Boolean> containsKey(K key);
CompletableFuture<Boolean> containsValue(V value);
CompletableFuture<Boolean> containsEntry(K key, V value);
CompletableFuture<Long> size();
boolean supportsDuplicates();
}
----

==== CompletableFuture<Void> put(K key, V value)
Puts a key-value pair in the multimap cache.

[source,java]
----
MultimapCache<String, String> multimapCache = ...;
multimapCache.put("girlNames", "marie")
.thenCompose(r1 -> multimapCache.put("girlNames", "oihana"))
.thenCompose(r3 -> multimapCache.get("girlNames"))
.thenAccept(names -> {
if(names.contains("marie"))
System.out.println("Marie is a girl name");
if(names.contains("oihana"))
System.out.println("Oihana is a girl name");
});
----
The output of this code is :

[source, txt]
----
Marie is a girl name
Oihana is a girl name
----

==== CompletableFuture<Collection<V>> get(K key)

Returns a view collection of the values associated with key in this multimap cache, if any. Any changes to the retrieved collection won't change the values in this multimap cache.
When this method returns an empty collection, it means the key was not found.


==== CompletableFuture<Boolean> remove(K key)
Removes the entry associated with the key from the multimap cache, if such exists.

==== CompletableFuture<Boolean> remove(K key, V value)
Removes a key-value pair from the multimap cache, if such exists.


==== CompletableFuture<Void> remove(Predicate<? super V> p)

==== CompletableFuture<Boolean> containsKey(K key)

==== CompletableFuture<Boolean> containsValue(V value)

==== CompletableFuture<Boolean> containsEntry(K key, V value)

==== CompletableFuture<Long> size()
Returns the number of key-value pairs in the multimap cache. It doesn't return the distinct number of keys.

==== boolean supportsDuplicates()


=== Creating a Multimap Cache

In version 9.2, the MultimapCache is configured as a regular cache. This can be done either by code or XML configuration.
See how to configure a regular Cache in the section link to [configure a cache].

==== Embedded mode

[source,java]
----
// create or obtain your EmbeddedCacheManager
EmbeddedCacheManager cm = ... ;
// create or obtain a MultimapCache passing the name, the cache manager and the configuration
MultimapCache multimapCache = EmbeddedMultimapCacheManagerFactory.get("test", cm, c.build());
----

==== Server mode

TODO

=== Limitations

In almost every case the Multimap Cache will behave as a regular Cache, but some limitations exist in the first 9.2 version.

==== Support for duplicates
Duplicates are not supported yet. This means that the multimap won't contain any duplicate key-value pair.
Whenever put method is called, if the key-value pair already exist, this key-value par won't be added.
Methods used to check if a key-value pair is already present in the Multimap are the `equals` and `hashcode`.

==== Eviction

For now, the eviction works per key, and not per key-value pair.
This means that whenever a key is evicted, all the values associated with the key will be evicted too.
Eviction per key-value could be supported in the future.

==== Transactions

Implicit transactions are supported through the auto-commit and all the methods are non blocking.
Explicit transactions work without blocking in most of the cases.
Methods that will block are `size`, `containsEntry` and `remove(Predicate<? super V> p)`
Expand Up @@ -37,3 +37,4 @@ include::rolling_upgrades.adoc[]
include::extending.adoc[]
include::architecture.adoc[]
include::counters.adoc[]
include::multimapcache.adoc[]
48 changes: 48 additions & 0 deletions multimap/pom.xml
@@ -0,0 +1,48 @@
<?xml version='1.0' encoding='UTF-8'?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-parent</artifactId>
<version>9.1.0-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>

<artifactId>infinispan-multimap</artifactId>
<packaging>jar</packaging>
<name>Infinispan Multimap</name>
<description>Infinispan Multimap module</description>

<properties>
<module.skipComponentMetaDataProcessing>false</module.skipComponentMetaDataProcessing>
</properties>

<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>infinispan-core</artifactId>
</dependency>
<dependency>
<groupId>org.kohsuke.metainf-services</groupId>
<artifactId>metainf-services</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>infinispan-core</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>infinispan-commons-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,38 @@
package org.infinispan.multimap.api;

import java.util.Collection;

import org.infinispan.Cache;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.multimap.api.MultimapCache;
import org.infinispan.multimap.impl.EmbeddedMultimapCache;

/**
* A {@link MultimapCache} factory for embedded cached.
*
* @author Katia Aresti, karesti@redhat.com
* @since 9.2
*/
public final class EmbeddedMultimapCacheManagerFactory {

private EmbeddedMultimapCacheManagerFactory() {
}

/**
* Factory used to create an embedded multimap cache.
*
* @param name, name of the multimap cache
* @param cacheManager, the cache manaher
* @param configuration, the configuration
* @return the {@link MultimapCache} created by {@link EmbeddedMultimapCache}
*/
public static <K, V> MultimapCache<K, V> get(String name, EmbeddedCacheManager cacheManager, Configuration configuration) {
if (cacheManager.getCacheConfiguration(name) == null) {
cacheManager.defineConfiguration(name, configuration);
}
Cache<K, Collection<V>> cache = cacheManager.getCache(name, true);
EmbeddedMultimapCache multimapCache = new EmbeddedMultimapCache(cache);
return multimapCache;
}
}

0 comments on commit 8693df7

Please sign in to comment.