/* * Copyright (c) 2008-2012, Hazel Bilisim Ltd. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hazelcast.core; import com.hazelcast.monitor.LocalMapStats; import com.hazelcast.query.Expression; import com.hazelcast.query.Predicate; import java.util.Collection; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * Concurrent, distributed, observable and queryable map. * <p/> * <p><b>This class is <i>not</i> a general-purpose <tt>ConcurrentMap</tt> implementation! While this class implements * the <tt>Map</tt> interface, it intentionally violates <tt>Map's</tt> general contract, which mandates the * use of the <tt>equals</tt> method when comparing objects. Instead of the equals method this implementation * compares the serialized byte version of the objects.</b> * <p/> * <p/> * <p/> * Read more: http://kickjava.com/src/java/util/IdentityHashMap.java.htm#ixzz1TCesQMzr * * @param <K> key * @param <V> value */ public interface IMap<K, V> extends ConcurrentMap<K, V>, Instance { /** * If this map has a MapStore and write-delay-seconds is * bigger than 0 (write-behind) then this method flushes * all the local dirty entries by calling MapStore.storeAll() */ void flush(); /** * Returns the name of this map * * @return name of this map */ String getName(); /** * Returns the entries for the given keys. * * @param keys keys to get * @return map of entries */ Map<K, V> getAll(Set<K> keys); /** * Asynchronously gets the given key. * <code> * Future future = map.getAsync(key); * // do some other stuff, when ready get the result * Object value = future.get(); * </code> * Future.get() will block until the actual map.get() completes. * If the application requires timely response, * then Future.get(timeout, timeunit) can be used. * <code> * try{ * Future future = map.getAsync(key); * Object value = future.get(40, TimeUnit.MILLISECOND); * }catch (TimeoutException t) { * // time wasn't enough * } * </code> * ExecutionException is never thrown. * * @param key the key of the map entry * @return Future from which the value of the key can be retrieved. * @see java.util.concurrent.Future */ Future<V> getAsync(K key); /** * Asynchronously puts the given key and value. * <code> * Future future = map.putAsync(key, value); * // do some other stuff, when ready get the result * Object oldValue = future.get(); * </code> * Future.get() will block until the actual map.get() completes. * If the application requires timely response, * then Future.get(timeout, timeunit) can be used. * <code> * try{ * Future future = map.putAsync(key, newValue); * Object oldValue = future.get(40, TimeUnit.MILLISECOND); * }catch (TimeoutException t) { * // time wasn't enough * } * </code> * ExecutionException is never thrown. * * @param key the key of the map entry * @param value the new value of the map entry * @return Future from which the old value of the key can be retrieved. * @see java.util.concurrent.Future */ Future<V> putAsync(K key, V value); /** * Asynchronously removes the given key. * * @param key The key of the map entry to remove. * @return A {@link java.util.concurrent.Future} from which the value * removed from the map can be retrieved. */ Future<V> removeAsync(K key); /** * Tries to remove the entry with the given key from this map * within specified timeout value. If the key is already locked by another * thread and/or member, then this operation will wait timeout * amount for acquiring the lock. * * @param key key of the entry * @param timeout maximum time to wait for acquiring the lock * for the key * @param timeunit time unit for the timeout * @return removed value of the entry * @throws java.util.concurrent.TimeoutException * if lock cannot be acquired for the given key within timeout */ Object tryRemove(K key, long timeout, TimeUnit timeunit) throws TimeoutException; /** * Tries to put the given key, value into this map within specified * timeout value. If this method returns false, it means that * the caller thread couldn't acquire the lock for the key within * timeout duration, thus put operation is not successful. * * @param key key of the entry * @param value value of the entry * @param timeout maximum time to wait * @param timeunit time unit for the timeout * @return <tt>true</tt> if the put is successful, <tt>false</tt> * otherwise. */ boolean tryPut(K key, V value, long timeout, TimeUnit timeunit); /** * Puts an entry into this map with a given ttl (time to live) value. * Entry will expire and get evicted after the ttl. If ttl is 0, then * the entry lives forever. * * @param key key of the entry * @param value value of the entry * @param ttl maximum time for this entry to stay in the map * 0 means infinite. * @param timeunit time unit for the ttl * @return old value of the entry */ V put(K key, V value, long ttl, TimeUnit timeunit); /** * Same as {@link #put(K, V, long, TimeUnit)} but MapStore, if defined, * will not be called to store/persist the entry. If ttl is 0, then * the entry lives forever. * * @param key key of the entry * @param value value of the entry * @param ttl maximum time for this entry to stay in the map. * 0 means infinite. * @param timeunit time unit for the ttl */ void putTransient(K key, V value, long ttl, TimeUnit timeunit); /** * Puts an entry into this map with a given ttl (time to live) value * if the specified key is not already associated with a value. * Entry will expire and get evicted after the ttl. * * @param key key of the entry * @param value value of the entry * @param ttl maximum time for this entry to stay in the map * @param timeunit time unit for the ttl * @return old value of the entry */ V putIfAbsent(K key, V value, long ttl, TimeUnit timeunit); /** * Puts an entry into this map with a given ttl (time to live) value. * Entry will expire and get evicted after the ttl. If ttl is 0, then * the entry lives forever. Similar to put operation except that set * doesn't return the old value which is more efficient. * * @param key key of the entry * @param value value of the entry * @param ttl maximum time for this entry to stay in the map * 0 means infinite. * @param timeunit time unit for the ttl * @return old value of the entry */ void set(K key, V value, long ttl, TimeUnit timeunit); /** * Tries to acquire the lock for the specified key and returns * the value of the key if lock is required in time. * <p>If the lock is not available then * the current thread becomes disabled for thread scheduling * purposes and lies dormant until one of two things happens: * <ul> * <li>The lock is acquired by the current thread; or * <li>The specified waiting time elapses * </ul> * * @param key key of the entry * @param time maximum time to wait for the lock * @param timeunit time unit of the <tt>time</tt> argument. * @return value of the key in this map * @throws java.util.concurrent.TimeoutException * if lock cannot be acquired in time. */ V tryLockAndGet(K key, long time, TimeUnit timeunit) throws TimeoutException; /** * Puts the key and value into this map and unlocks the key * if the calling thread owns the lock. * * @param key key of the entry * @param value value of the entry */ void putAndUnlock(K key, V value); /** * Acquires the lock for the specified key. * <p>If the lock is not available then * the current thread becomes disabled for thread scheduling * purposes and lies dormant until the lock has been acquired. * <p/> * Scope of the lock is this map only. * Acquired lock is only for the key in this map. * <p/> * Locks are re-entrant so if the key is locked N times then * it should be unlocked N times before another thread can acquire it. * * @param key key to lock. */ void lock(K key); /** * Tries to acquire the lock for the specified key. * <p>If the lock is not available then the current thread * doesn't wait and returns false immediately. * * @param key key to lock. * @return <tt>true</tt> if lock is acquired, <tt>false</tt> otherwise. */ boolean tryLock(K key); /** * Tries to acquire the lock for the specified key. * <p>If the lock is not available then * the current thread becomes disabled for thread scheduling * purposes and lies dormant until one of two things happens: * <ul> * <li>The lock is acquired by the current thread; or * <li>The specified waiting time elapses * </ul> * * @param key key to lock in this map * @param time maximum time to wait for the lock * @param timeunit time unit of the <tt>time</tt> argument. * @return <tt>true</tt> if the lock was acquired and <tt>false</tt> * if the waiting time elapsed before the lock was acquired. */ boolean tryLock(K key, long time, TimeUnit timeunit); /** * Releases the lock for the specified key. It never blocks and * returns immediately. * * @param key key to lock. */ void unlock(K key); /** * Releases the lock for the specified key regardless of the lock owner. * It always successfully unlocks the key, never blocks * and returns immediately. * * @param key key to lock. */ void forceUnlock(K key); /** * Tries to acquire the lock for the entire map. * The thread that locks the map can do all the operations * but other threads in the cluster cannot operate on the map. * <p>If the lock is not available then * the current thread becomes disabled for thread scheduling * purposes and lies dormant until one of two things happens: * <ul> * <li>The lock is acquired by the current thread; or * <li>The specified waiting time elapses * </ul> * * @param time maximum time to wait for the lock * @param timeunit time unit of the <tt>time</tt> argument. * @return <tt>true</tt> if the lock was acquired and <tt>false</tt> * if the waiting time elapsed before the lock was acquired. */ boolean lockMap(long time, TimeUnit timeunit); /** * Unlocks the map. It never blocks and * returns immediately. */ void unlockMap(); /** * Adds a local entry listener for this map. Added listener will be only * listening for the events (add/remove/update/evict) of the locally owned entries. * <p/> * Note that entries in distributed map are partitioned across * the cluster members; each member owns and manages the some portion of the * entries. Owned entries are called local entries. This * listener will be listening for the events of local entries. Let's say * your cluster has member1 and member2. On member2 you added a local listener and from * member1, you call <code>map.put(key2, value2)</code>. * If the key2 is owned by member2 then the local listener will be * notified for the add/update event. Also note that entries can migrate to * other nodes for load balancing and/or membership change. * * @param listener entry listener * @see #localKeySet() */ void addLocalEntryListener(EntryListener<K, V> listener); /** * Adds an entry listener for this map. Listener will get notified * for all map add/remove/update/evict events. * * @param listener entry listener * @param includeValue <tt>true</tt> if <tt>EntryEvent</tt> should * contain the value. */ void addEntryListener(EntryListener<K, V> listener, boolean includeValue); /** * Removes the specified entry listener * Returns silently if there is no such listener added before. * * @param listener entry listener */ void removeEntryListener(EntryListener<K, V> listener); /** * Adds the specified entry listener for the specified key. * The listener will get notified for all * add/remove/update/evict events of the specified key only. * * @param listener entry listener * @param key key to listen * @param includeValue <tt>true</tt> if <tt>EntryEvent</tt> should * contain the value. */ void addEntryListener(EntryListener<K, V> listener, K key, boolean includeValue); /** * Removes the specified entry listener for the specified key. * Returns silently if there is no such listener added before for * the key. * * @param listener * @param key */ void removeEntryListener(EntryListener<K, V> listener, K key); /** * Returns the <tt>MapEntry</tt> for the specified key. * * @param key key of the entry * @return <tt>MapEntry</tt> of the specified key * @see MapEntry */ MapEntry<K, V> getMapEntry(K key); /** * Evicts the specified key from this map. If * a <tt>MapStore</tt> defined for this map, then the entry is not * deleted from the underlying <tt>MapStore</tt>, evict only removes * the entry from the memory. * * @param key key to evict * @return <tt>true</tt> if the key is evicted, <tt>false</tt> otherwise. */ boolean evict(Object key); /** * Queries the map based on the specified predicate and * returns the keys of matching entries. * <p/> * Specified predicate runs on all members in parallel. * * @param predicate query criteria * @return result key set of the query */ Set<K> keySet(Predicate predicate); /** * Queries the map based on the specified predicate and * returns the matching entries. * <p/> * Specified predicate runs on all members in parallel. * * @param predicate query criteria * @return result entry set of the query */ Set<Map.Entry<K, V>> entrySet(Predicate predicate); /** * Queries the map based on the specified predicate and * returns the values of matching entries. * <p/> * Specified predicate runs on all members in parallel. * * @param predicate query criteria * @return result value collection of the query */ Collection<V> values(Predicate predicate); /** * Returns the locally owned set of keys. * <p/> * Each key in this map is owned and managed by a specific * member in the cluster. * <p/> * Note that ownership of these keys might change over time * so that key ownerships can be almost evenly distributed * in the cluster. * * @return locally owned keys. */ Set<K> localKeySet(); /** * Returns the keys of matching locally owned entries. * <p/> * Each key in this map is owned and managed by a specific * member in the cluster. * <p/> * Note that ownership of these keys might change over time * so that key ownerships can be almost evenly distributed * in the cluster. * * @param predicate query criteria * @return keys of matching locally owned entries. */ Set<K> localKeySet(Predicate predicate); /** * Adds an index to this map for the specified entries so * that queries can run faster. * <p/> * Let's say your map values are Employee objects. * <pre> * public class Employee implements Serializable { * private boolean active = false; * private int age; * private String name = null; * // other fields. * * // getters setter * * } * </pre> * <p/> * If you are querying your values mostly based on age and active then * you should consider indexing these fields. * <pre> * IMap imap = Hazelcast.getMap("employees"); * imap.addIndex("age", true); // ordered, since we have ranged queries for this field * imap.addIndex("active", false); // not ordered, because boolean field cannot have range * </pre> * <p/> * Index attribute should either have a getter method or be public. * You should also make sure to add the indexes before adding * entries to this map. * * @param attribute attribute of value * @param ordered <tt>true</tt> if index should be ordered, * <tt>false</tt> otherwise. */ void addIndex(String attribute, boolean ordered); /** * Adds an index to this map based on the provided expression. * * @param expression expression for the index. * @param ordered <tt>true</tt> if index should be ordered, * <tt>false</tt> otherwise. */ void addIndex(Expression<?> expression, boolean ordered); /** * Returns LocalMapStats for this map. * LocalMapStats is the statistics for the local portion of this * distributed map and contains information such as ownedEntryCount * backupEntryCount, lastUpdateTime, lockedEntryCount. * <p/> * Since this stats are only for the local portion of this map, if you * need the cluster-wide MapStats then you need to get the LocalMapStats * from all members of the cluster and combine them. * * @return this map's local statistics. */ LocalMapStats getLocalMapStats(); }