Skip to content

Commit

Permalink
ignite-96 fixed evictions
Browse files Browse the repository at this point in the history
  • Loading branch information
Yakov Zhdanov committed Feb 11, 2015
1 parent 7e8b6c7 commit db9d607
Show file tree
Hide file tree
Showing 14 changed files with 826 additions and 723 deletions.
Expand Up @@ -17,6 +17,7 @@

package org.apache.ignite.cache.eviction;

import org.apache.ignite.*;
import org.jetbrains.annotations.*;

import javax.cache.*;
Expand All @@ -28,12 +29,25 @@
* @version @java.version
*/
public interface EvictableEntry<K, V> extends Cache.Entry<K, V> {
/**
* Evicts entry associated with given key from cache. Note, that entry will be evicted
* only if it's not used (not participating in any locks or transactions).
*
* @return {@code True} if entry could be evicted, {@code false} otherwise.
*/
public boolean evict();

/**
* Checks whether entry is currently present in cache or not. If entry is not in
* cache (e.g. has been removed) {@code false} is returned. In this case all
* operations on this entry will cause creation of a new entry in cache.
*
* @return {@code True} if entry is in cache, {@code false} otherwise.
*/
public boolean isCached();

/**
* Gets metadata by name.
* Gets metadata added by eviction policy.
*
* @return Metadata value or {@code null}.
*/
Expand All @@ -43,7 +57,7 @@ public interface EvictableEntry<K, V> extends Cache.Entry<K, V> {
* Adds a new metadata.
*
* @param val Metadata value.
* @return Metadata previously associated with given name, or
* @return Metadata previously added, or
* {@code null} if there was none.
*/
@Nullable public <T> T addMeta(T val);
Expand Down
Expand Up @@ -184,7 +184,7 @@ else if (!entry.removeMeta(node))
* @return Peeked value.
*/
@Nullable private byte[] peek(EvictableEntry<GridGgfsBlockKey, byte[]> entry) {
return (byte[])((GridCacheEvictionEntry)entry).peek();
return (byte[])((EvictableEntryImpl)entry).peek();
}

/**
Expand Down
Expand Up @@ -17,10 +17,13 @@

package org.apache.ignite.cache.eviction.random;

import org.apache.ignite.*;
import org.apache.ignite.cache.eviction.*;
import org.apache.ignite.configuration.*;
import org.apache.ignite.internal.util.typedef.internal.*;

import javax.cache.*;

/**
* Cache eviction policy which will select random cache entry for eviction if cache
* size exceeds the {@link #getMaxSize()} parameter. This implementation is
Expand Down Expand Up @@ -74,22 +77,21 @@ public CacheRandomEvictionPolicy(int max) {
}

/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override public void onEntryAccessed(boolean rmv, EvictableEntry<K, V> entry) {
if (!entry.isCached())
return;

assert false : "ignite-96";
// TODO ignite-96
// GridCache<K, V> cache = entry.projection().cache();
//
// int size = cache.size();
//
// for (int i = max; i < size; i++) {
// Entry<K, V> e = cache.randomEntry();
//
// if (e != null)
// e.evict();
// }
IgniteCache<K, V> cache = entry.unwrap(IgniteCache.class);

int size = cache.size();

for (int i = max; i < size; i++) {
Cache.Entry<K, V> e = cache.randomEntry();

if (e != null)
e.unwrap(EvictableEntry.class).evict();
}
}

/** {@inheritDoc} */
Expand Down
Expand Up @@ -19,35 +19,28 @@

import org.apache.ignite.*;
import org.apache.ignite.cache.eviction.*;
import org.apache.ignite.internal.processors.cache.transactions.*;
import org.apache.ignite.internal.util.lang.*;
import org.apache.ignite.internal.util.tostring.*;
import org.apache.ignite.internal.util.typedef.internal.*;
import org.jetbrains.annotations.*;

import java.io.*;

/**
* Entry wrapper that never obscures obsolete entries from user.
*/
public class GridCacheEvictionEntry<K, V> implements EvictableEntry<K, V> {
public class EvictableEntryImpl<K, V> implements EvictableEntry<K, V> {
/** */
private static final String META_KEY = "ignite-eviction-entry-meta";

/** Cached entry. */
@GridToStringInclude
protected GridCacheEntryEx<K, V> cached;

/**
* Empty constructor required for {@link Externalizable}.
*/
public GridCacheEvictionEntry() {
// No-op.
}

/**
* @param cached Cached entry.
*/
@SuppressWarnings({"TypeMayBeWeakened"})
protected GridCacheEvictionEntry(GridCacheEntryEx<K, V> cached) {
protected EvictableEntryImpl(GridCacheEntryEx<K, V> cached) {
this.cached = cached;
}

Expand Down Expand Up @@ -79,6 +72,7 @@ protected GridCacheEvictionEntry(GridCacheEntryEx<K, V> cached) {
/**
* @return Peeks value.
*/
@SuppressWarnings("unchecked")
@Nullable public V peek() {
try {
return cached.peek(GridCachePeekMode.GLOBAL);
Expand All @@ -89,48 +83,76 @@ protected GridCacheEvictionEntry(GridCacheEntryEx<K, V> cached) {
}

/** {@inheritDoc} */
@Nullable @Override public V getValue() throws IllegalStateException {
throw new UnsupportedOperationException("Operation not supported during eviction.");
@SuppressWarnings("unchecked")
@Override public V getValue() {
try {
IgniteInternalTx<K, V> tx = cached.context().tm().userTx();

if (tx != null) {
GridTuple<V> peek = tx.peek(cached.context(), false, cached.key(), null);

if (peek != null)
return peek.get();
}

if (cached.detached())
return cached.rawGet();

for (;;) {
GridCacheEntryEx<K, V> e = cached.context().cache().peekEx(cached.key());

if (e == null)
return null;

try {
return e.peek(GridCachePeekMode.GLOBAL, CU.<K, V>empty());
}
catch (GridCacheEntryRemovedException ignored) {
// No-op.
}
}
}
catch (GridCacheFilterFailedException ignored) {
throw new IgniteException("Should never happen.");
}
}

/** {@inheritDoc} */
@SuppressWarnings({"unchecked"})
@Nullable @Override public <T> T addMeta(T val) {
return cached.addMeta(META_KEY, val);
}

/** {@inheritDoc} */
@SuppressWarnings({"unchecked"})
@Nullable @Override public <T> T meta() {
return cached.meta(META_KEY);
}

/** {@inheritDoc} */
@SuppressWarnings({"unchecked"})
@Nullable @Override public <T> T removeMeta() {
return cached.removeMeta(META_KEY);
}

/** {@inheritDoc} */
@SuppressWarnings({"unchecked"})
@Override public <T> boolean removeMeta(T val) {
return cached.removeMeta(META_KEY, val);
}

/** {@inheritDoc} */
@SuppressWarnings({"unchecked"})
@Nullable @Override public <T> T putMetaIfAbsent(T val) {
return cached.putMetaIfAbsent(META_KEY, val);
}

/** {@inheritDoc} */
@SuppressWarnings({"RedundantTypeArguments"})
@Override public <T> boolean replaceMeta(T curVal, T newVal) {
return cached.replaceMeta(META_KEY,curVal, newVal);
}

/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override public <T> T unwrap(Class<T> clazz) {
if (clazz.isAssignableFrom(IgniteCache.class))
return (T)cached.context().grid().jcache(cached.context().name());

if(clazz.isAssignableFrom(getClass()))
return clazz.cast(this);

Expand All @@ -148,8 +170,8 @@ protected GridCacheEvictionEntry(GridCacheEntryEx<K, V> cached) {
if (obj == this)
return true;

if (obj instanceof GridCacheEvictionEntry) {
GridCacheEvictionEntry<K, V> other = (GridCacheEvictionEntry<K, V>)obj;
if (obj instanceof EvictableEntryImpl) {
EvictableEntryImpl<K, V> other = (EvictableEntryImpl<K, V>)obj;

return cached.key().equals(other.getKey());
}
Expand All @@ -159,6 +181,6 @@ protected GridCacheEvictionEntry(GridCacheEntryEx<K, V> cached) {

/** {@inheritDoc} */
@Override public String toString() {
return S.toString(GridCacheEvictionEntry.class, this);
return S.toString(EvictableEntryImpl.class, this);
}
}
Expand Up @@ -4057,7 +4057,7 @@ IgniteInternalFuture<?> globalLoadCacheAsync(@Nullable IgniteBiPredicate<K, V> p
@Nullable @Override public Cache.Entry<K, V> randomEntry() {
GridCacheMapEntry<K, V> e = map.randomEntry();

return e == null || e.obsolete() ? null : e.wrap();
return e == null || e.obsolete() ? null : e.wrapLazyValue();
}

/** {@inheritDoc} */
Expand Down
Expand Up @@ -3707,7 +3707,7 @@ protected V saveValueForIndexUnlocked() throws IgniteCheckedException {

/** {@inheritDoc} */
@Override public Cache.Entry<K, V> wrapLazyValue() {
return new IteratorEntry(key);
return new LazyValueEntry(key);
}

/** {@inheritDoc} */
Expand All @@ -3717,7 +3717,7 @@ protected V saveValueForIndexUnlocked() throws IgniteCheckedException {

/** {@inheritDoc} */
@Override public EvictableEntry<K, V> wrapEviction() {
return new GridCacheEvictionEntry<>(this);
return new EvictableEntryImpl<>(this);
}

/** {@inheritDoc} */
Expand Down Expand Up @@ -4319,14 +4319,14 @@ private V unmarshalOffheap(boolean tmp) throws IgniteCheckedException {
/**
*
*/
private class IteratorEntry implements Cache.Entry<K, V> {
private class LazyValueEntry implements Cache.Entry<K, V> {
/** */
private final K key;

/**
* @param key Key.
*/
private IteratorEntry(K key) {
private LazyValueEntry(K key) {
this.key = key;
}

Expand Down Expand Up @@ -4373,6 +4373,12 @@ private IteratorEntry(K key) {
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override public <T> T unwrap(Class<T> cls) {
if (cls.isAssignableFrom(IgniteCache.class))
return (T)cctx.grid().jcache(cctx.name());

if (cls.isAssignableFrom(EvictableEntry.class))
return (T)wrapEviction();

if (!cls.equals(getClass()))
throw new IllegalArgumentException("Unwrapping to class is not supported: " + cls);

Expand Down
Expand Up @@ -114,8 +114,6 @@ public void testEvictions() throws Exception {

int oldSize = cache1.localSize();

assert false;

IgniteInternalFuture fut = multithreadedAsync(
new Callable<Object>() {
@Nullable @Override public Object call() throws Exception {
Expand Down
Expand Up @@ -228,8 +228,8 @@ private void checkEvictions() throws Throwable {
info("Near node near key set: " + new TreeSet<>(this.<Integer, Integer>near(2).keySet()));

try {
assert cache.size() == 10 : "Invalid cache size [size=" + cache.size() + ']';
assert cache.size() == 10 : "Invalid key size [size=" + cache.size() + ']';
assert cache.localSize() == 10 : "Invalid cache size [size=" + cache.localSize() + ']';
assert cache.localSize() == 10 : "Invalid key size [size=" + cache.localSize() + ']';

assert jcache(2).localSize() == 0;

Expand Down
Expand Up @@ -208,7 +208,7 @@ private void checkImplicitTx(IgniteCache<String, String> cache) throws Exception

asyncCache.getAll(F.asSet("key5", "key6"));

assertTrue(((Collection)asyncCache.future().get()).isEmpty());
assertTrue(((Map)asyncCache.future().get()).isEmpty());

cache.put("key7", "key7");
cache.remove("key7", "key7");
Expand Down Expand Up @@ -266,7 +266,7 @@ private void checkExplicitTx(Ignite ignite, IgniteCache<String, String> cache) t
try {
asyncCache.getAll(F.asSet("key5", "key6"));

assertTrue(((Collection)asyncCache.future().get()).isEmpty());
assertTrue(((Map)asyncCache.future().get()).isEmpty());

tx.commit();
}
Expand Down

0 comments on commit db9d607

Please sign in to comment.