http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheCountDownLatch.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheCountDownLatch.java b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheCountDownLatch.java new file mode 100644 index 0000000..1e90237 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheCountDownLatch.java @@ -0,0 +1,227 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.datastructures; + +import org.apache.ignite.*; +import org.gridgain.grid.*; + +import java.util.concurrent.*; + +/** + * This interface provides a rich API for working with distributed count down latch. + * <p> + * <h1 class="header">Functionality</h1> + * Distributed count down latch provides functionality similar to {@code java.util.CountDownLatch}. + * Note that you cannot remove count down latch having count greater that zero. It should be + * counted down to zero first. + * <h1 class="header">Creating Distributed Count Down Latch</h1> + * Instance of cache count down latch can be created by calling the following method: + * {@link GridCacheDataStructures#countDownLatch(String, int, boolean, boolean)}. + * @see GridCacheDataStructures#countDownLatch(String, int, boolean, boolean) + * @see GridCacheDataStructures#removeCountDownLatch(String) + */ +public interface GridCacheCountDownLatch { + /** + * Gets name of the latch. + * + * @return Name of the latch. + */ + public String name(); + + /** + * Gets current count value of the latch. + * + * @return Current count. + */ + public int count(); + + /** + * Gets initial count value of the latch. + * + * @return Initial count. + */ + public int initialCount(); + + /** + * Gets {@code autoDelete} flag. If this flag is {@code true} latch is removed + * from cache when it has been counted down to 0. + * + * @return Value of {@code autoDelete} flag. + */ + public boolean autoDelete(); + + /** + * Causes the current thread to wait until the latch has counted down to + * zero, unless current thread is interrupted. + * <p> + * If the current count of the latch is zero then this method returns immediately. + * <p> + * If the current count is greater than zero then the current + * thread becomes disabled for thread scheduling purposes and lies + * dormant until one of two things happen: + * <ul> + * <li>The count reaches zero due to invocations of the + * {@link #countDown} method on any node; or + * <li>Some other thread interrupts the current thread. + * </ul> + * <p> + * If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is interrupted while waiting, + * </ul> + * then {@link GridInterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * + * @throws IgniteCheckedException If operation failed. + * @throws GridInterruptedException if the current thread is interrupted + * while waiting + */ + public void await() throws IgniteCheckedException; + + /** + * Causes the current thread to wait until the latch has counted down to + * zero, unless the thread is interrupted, or the specified waiting time elapses. + * <p> + * If the current count is zero then this method returns immediately + * with the value {@code true}. + * <p> + * If the current count is greater than zero then the current + * thread becomes disabled for thread scheduling purposes and lies + * dormant until one of three things happen: + * <ul> + * <li>The count reaches zero due to invocations of the + * {@link #countDown} method on any node; or + * <li>Some other thread interrupts the current thread; or + * <li>The specified waiting time elapses. + * </ul> + * <p> + * If the count reaches zero then the method returns with the + * value {@code true}. + * <p> + * If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is interrupted while waiting, + * </ul> + * then {@link GridInterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * <p> + * If the specified waiting time elapses then the value {@code false} + * is returned. If the time is less than or equal to zero, the method + * will not wait at all. + * + * @param timeout The maximum time to wait in milliseconds. + * @return {@code True} if the count reached zero and {@code false} + * if the waiting time elapsed before the count reached zero. + * @throws GridInterruptedException If the current thread is interrupted + * while waiting. + * @throws IgniteCheckedException If operation failed. + */ + public boolean await(long timeout) throws IgniteCheckedException; + + /** + * Causes the current thread to wait until the latch has counted down to + * zero, unless the thread is interrupted, or the specified waiting time elapses. + * <p> + * If the current count is zero then this method returns immediately + * with the value {@code true}. + * <p> + * If the current count is greater than zero then the current + * thread becomes disabled for thread scheduling purposes and lies + * dormant until one of three things happen: + * <ul> + * <li>The count reaches zero due to invocations of the + * {@link #countDown} method on any node; or + * <li>Some other thread interrupts the current thread; or + * <li>The specified waiting time elapses. + * </ul> + * <p> + * If the count reaches zero then the method returns with the + * value {@code true}. + * <p> + * If the current thread: + * <ul> + * <li>has its interrupted status set on entry to this method; or + * <li>is interrupted while waiting, + * </ul> + * then {@link GridInterruptedException} is thrown and the current thread's + * interrupted status is cleared. + * <p> + * If the specified waiting time elapses then the value {@code false} + * is returned. If the time is less than or equal to zero, the method + * will not wait at all. + * + * + * @param timeout The maximum time to wait. + * @param unit The time unit of the {@code timeout} argument. + * @return {@code True} if the count reached zero and {@code false} + * if the waiting time elapsed before the count reached zero. + * @throws GridInterruptedException If the current thread is interrupted + * while waiting. + * @throws IgniteCheckedException If operation failed. + */ + public boolean await(long timeout, TimeUnit unit) throws IgniteCheckedException; + + /** + * Decrements the count of the latch, releasing all waiting threads + * on all nodes if the count reaches zero. + * <p> + * If the current count is greater than zero then it is decremented. + * If the new count is zero then all waiting threads are re-enabled for + * thread scheduling purposes. + * <p> + * If the current count equals zero then nothing happens. + * + * @return Count after decrement. + * @throws IgniteCheckedException If operation failed. + */ + public int countDown() throws IgniteCheckedException; + + /** + * Decreases the count of the latch using passed in value, + * releasing all waiting threads on all nodes if the count reaches zero. + * <p> + * If the current count is greater than zero then it is decreased. + * If the new count is zero then all waiting threads are re-enabled for + * thread scheduling purposes. + * <p> + * If the current count equals zero then nothing happens. + * + * @param val Value to decrease counter on. + * @return Count after decreasing. + * @throws IgniteCheckedException If operation failed. + */ + public int countDown(int val) throws IgniteCheckedException; + + /** + * Counts down this latch to zero, releasing all waiting threads on all nodes. + * <p> + * If the current count equals zero then nothing happens. + * + * @throws IgniteCheckedException If operation failed. + */ + public void countDownAll() throws IgniteCheckedException; + + /** + * Gets {@code removed} status of the latch. + * + * @return {@code True} if latch was removed from cache, {@code false} otherwise. + */ + public boolean removed(); +}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureInvalidException.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureInvalidException.java b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureInvalidException.java new file mode 100644 index 0000000..dfde5de --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureInvalidException.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.datastructures; + +import org.apache.ignite.*; +import org.jetbrains.annotations.*; + +/** + * This checked exception gets thrown if attempt to access an invalid data structure has been made. + * Data structure may become invalid if communication with remote nodes has been lost or + * any other error condition happened that prevented from insuring consistent state. + * <p> + * The best way to handle this error is to discard the invalid data structure instance and try + * getting the underlying data structure from cache again. + * <p> + * Note that data structures throw runtime exceptions out of methods that don't have + * checked exceptions in the signature. + */ +public class GridCacheDataStructureInvalidException extends IgniteCheckedException { + /** */ + private static final long serialVersionUID = 0L; + + /** + * Creates new exception with given error message. + * + * @param msg Error message. + */ + public GridCacheDataStructureInvalidException(String msg) { + super(msg); + } + + /** + * Creates new exception with given throwable as a nested cause and + * source of error message. + * + * @param cause Non-null throwable cause. + */ + public GridCacheDataStructureInvalidException(Throwable cause) { + this(cause.getMessage(), cause); + } + + /** + * Creates a new exception with given error message and optional nested cause exception. + * + * @param msg Error message. + * @param cause Optional nested exception (can be {@code null}). + */ + public GridCacheDataStructureInvalidException(String msg, @Nullable Throwable cause) { + super(msg, cause); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureInvalidRuntimeException.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureInvalidRuntimeException.java b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureInvalidRuntimeException.java new file mode 100644 index 0000000..7ca87e1 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureInvalidRuntimeException.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.datastructures; + +import org.apache.ignite.*; +import org.jetbrains.annotations.*; + +/** + * This runtime exception gets thrown if attempt to access an invalid data structure has been made. + * Data structure may become invalid if communication with remote nodes has been lost or + * any other error condition happened that prevented from insuring consistent state. + * <p> + * The best way to handle this error is to discard the invalid data structure instance and try + * getting the underlying data structure from cache again. + * <p> + * Note that data structures throw runtime exceptions out of methods that don't have + * checked exceptions in the signature. + */ +public class GridCacheDataStructureInvalidRuntimeException extends IgniteException { + /** */ + private static final long serialVersionUID = 0L; + + /** + * Creates new exception with given error message. + * + * @param msg Error message. + */ + public GridCacheDataStructureInvalidRuntimeException(String msg) { + super(msg); + } + + /** + * Creates new exception with given throwable as a nested cause and + * source of error message. + * + * @param cause Non-null throwable cause. + */ + public GridCacheDataStructureInvalidRuntimeException(Throwable cause) { + this(cause.getMessage(), cause); + } + + /** + * Creates a new exception with given error message and optional nested cause exception. + * + * @param msg Error message. + * @param cause Optional nested exception (can be {@code null}). + */ + public GridCacheDataStructureInvalidRuntimeException(String msg, @Nullable Throwable cause) { + super(msg, cause); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureRemovedException.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureRemovedException.java b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureRemovedException.java new file mode 100644 index 0000000..8427ee9 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureRemovedException.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.datastructures; + +import org.apache.ignite.*; +import org.jetbrains.annotations.*; + +/** + * This checked exception gets thrown if attempt to access a removed data structure has been made. + * <p> + * Note that data structures throw runtime exceptions out of methods that don't have + * checked exceptions in the signature. + */ +public class GridCacheDataStructureRemovedException extends IgniteCheckedException { + /** */ + private static final long serialVersionUID = 0L; + + /** + * Creates new exception with given error message. + * + * @param msg Error message. + */ + public GridCacheDataStructureRemovedException(String msg) { + super(msg); + } + + /** + * Creates new exception with given throwable as a nested cause and + * source of error message. + * + * @param cause Non-null throwable cause. + */ + public GridCacheDataStructureRemovedException(Throwable cause) { + this(cause.getMessage(), cause); + } + + /** + * Creates a new exception with given error message and optional nested cause exception. + * + * @param msg Error message. + * @param cause Optional nested exception (can be {@code null}). + */ + public GridCacheDataStructureRemovedException(String msg, @Nullable Throwable cause) { + super(msg, cause); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureRemovedRuntimeException.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureRemovedRuntimeException.java b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureRemovedRuntimeException.java new file mode 100644 index 0000000..31ebedf --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructureRemovedRuntimeException.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.datastructures; + +import org.apache.ignite.*; +import org.jetbrains.annotations.*; + +/** + * This runtime exception gets thrown if attempt to access a removed data structure has been made. + * <p> + * Note that data structures throw runtime exceptions out of methods that don't have + * checked exceptions in the signature. + */ +public class GridCacheDataStructureRemovedRuntimeException extends IgniteException { + /** */ + private static final long serialVersionUID = 0L; + + /** + * Creates new exception with given error message. + * + * @param msg Error message. + */ + public GridCacheDataStructureRemovedRuntimeException(String msg) { + super(msg); + } + + /** + * Creates new exception with given throwable as a nested cause and + * source of error message. + * + * @param cause Non-null throwable cause. + */ + public GridCacheDataStructureRemovedRuntimeException(Throwable cause) { + this(cause.getMessage(), cause); + } + + /** + * Creates a new exception with given error message and optional nested cause exception. + * + * @param msg Error message. + * @param cause Optional nested exception (can be {@code null}). + */ + public GridCacheDataStructureRemovedRuntimeException(String msg, @Nullable Throwable cause) { + super(msg, cause); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructures.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructures.java b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructures.java new file mode 100644 index 0000000..72855f1 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheDataStructures.java @@ -0,0 +1,221 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.datastructures; + +import org.apache.ignite.*; +import org.gridgain.grid.cache.*; +import org.jetbrains.annotations.*; + +/** + * Facade for working with distributed cache data structures. All cache data structures are similar + * in APIs to {@code 'java.util.concurrent'} package, but all operations on them are grid-aware. + * For example, if you increment {@link GridCacheAtomicLong} on one node, another node will + * know about the change. Or if you add an element to {@link GridCacheQueue} on one node, + * you can poll it on another node. + * <p> + * You can get data structures facade by calling {@link org.apache.ignite.cache.GridCache#dataStructures()} method. + */ +public interface GridCacheDataStructures { + /** + * Will get an atomic sequence from cache and create one if it has not been created yet and {@code create} flag + * is {@code true}. + * + * @param name Sequence name. + * @param initVal Initial value for sequence. If sequence already cached, {@code initVal} will be ignored. + * @param create Boolean flag indicating whether data structure should be created if does not exist. + * @return Sequence for the given name. + * @throws IgniteCheckedException If sequence could not be fetched or created. + */ + @Nullable public GridCacheAtomicSequence atomicSequence(String name, long initVal, boolean create) + throws IgniteCheckedException; + + /** + * Remove sequence from cache. + * + * @param name Sequence name. + * @return {@code True} if sequence has been removed, {@code false} otherwise. + * @throws IgniteCheckedException If remove failed. + */ + public boolean removeAtomicSequence(String name) throws IgniteCheckedException; + + /** + * Will get a atomic long from cache and create one if it has not been created yet and {@code create} flag + * is {@code true}. + * + * @param name Name of atomic long. + * @param initVal Initial value for atomic long. If atomic long already cached, {@code initVal} + * will be ignored. + * @param create Boolean flag indicating whether data structure should be created if does not exist. + * @return Atomic long. + * @throws IgniteCheckedException If atomic long could not be fetched or created. + */ + @Nullable public GridCacheAtomicLong atomicLong(String name, long initVal, boolean create) throws IgniteCheckedException; + + /** + * Remove atomic long from cache. + * + * @param name Name of atomic long. + * @return {@code True} if atomic long has been removed, {@code false} otherwise. + * @throws IgniteCheckedException If removing failed. + */ + public boolean removeAtomicLong(String name) throws IgniteCheckedException; + + /** + * Will get a named queue from cache and create one if it has not been created yet and {@code create} flag + * is {@code true}. + * If queue is present in cache already, queue properties will not be changed. Use + * collocation for {@link org.apache.ignite.cache.GridCacheMode#PARTITIONED} caches if you have lots of relatively + * small queues as it will make fetching, querying, and iteration a lot faster. If you have + * few very large queues, then you should consider turning off collocation as they simply + * may not fit in a single node's memory. However note that in this case + * to get a single element off the queue all nodes may have to be queried. + * + * @param name Name of queue. + * @param cap Capacity of queue, {@code 0} for unbounded queue. + * @param collocated If {@code true} then all items within the same queue will be collocated on the same node. + * Otherwise elements of the same queue maybe be cached on different nodes. If you have lots of relatively + * small queues, then you should use collocation. If you have few large queues, then you should turn off + * collocation. This parameter works only for {@link org.apache.ignite.cache.GridCacheMode#PARTITIONED} cache. + * @param create Boolean flag indicating whether data structure should be created if does not exist. + * @return Queue with given properties. + * @throws IgniteCheckedException If remove failed. + */ + @Nullable public <T> GridCacheQueue<T> queue(String name, int cap, boolean collocated, + boolean create) throws IgniteCheckedException; + + /** + * Remove queue from cache. Internally one transaction will be created for all elements + * in the queue. If you anticipate that queue may be large, then it's better to use + * {@link #removeQueue(String, int)} which allows to specify batch size. In that case + * transaction will be split into multiple transactions which will have upto {@code batchSize} + * elements in it. + * + * @param name Name queue. + * @return {@code True} if queue has been removed and false if it's not cached. + * @throws IgniteCheckedException If remove failed. + */ + public boolean removeQueue(String name) throws IgniteCheckedException; + + /** + * Remove queue from cache. Internally multiple transactions will be created + * with no more than {@code batchSize} elements in them. For larger queues, this + * method is preferrable over {@link #removeQueue(String)} which will create only + * one transaction for the whole operation. + * + * @param name Name queue. + * @param batchSize Batch size. + * @return {@code True} if queue has been removed and false if it's not cached. + * @throws IgniteCheckedException If remove failed. + */ + public boolean removeQueue(String name, int batchSize) throws IgniteCheckedException; + + /** + * Will get a named set from cache and create one if it has not been created yet and {@code create} flag + * is {@code true}. + * + * @param name Set name. + * @param collocated If {@code true} then all items within the same set will be collocated on the same node. + * Otherwise elements of the same set maybe be cached on different nodes. This parameter works only + * for {@link org.apache.ignite.cache.GridCacheMode#PARTITIONED} cache. + * @param create Flag indicating whether set should be created if does not exist. + * @return Set with given properties. + * @throws IgniteCheckedException If failed. + */ + @Nullable public <T> GridCacheSet<T> set(String name, boolean collocated, boolean create) throws IgniteCheckedException; + + /** + * Removes set from cache. + * + * @param name Set name. + * @return {@code True} if set has been removed and false if it's not cached. + * @throws IgniteCheckedException If failed. + */ + public boolean removeSet(String name) throws IgniteCheckedException; + + /** + * Will get a atomic reference from cache and create one if it has not been created yet and {@code create} flag + * is {@code true}. + * + * @param name Atomic reference name. + * @param initVal Initial value for atomic reference. If atomic reference already cached, + * {@code initVal} will be ignored. + * @param create Boolean flag indicating whether data structure should be created if does not exist. + * @return Atomic reference for the given name. + * @throws IgniteCheckedException If atomic reference could not be fetched or created. + */ + @Nullable public <T> GridCacheAtomicReference<T> atomicReference(String name, @Nullable T initVal, boolean create) + throws IgniteCheckedException; + + /** + * Remove atomic reference from cache. + * + * @param name Atomic reference name. + * @return {@code True} if atomic reference has been removed, {@code false} otherwise. + * @throws IgniteCheckedException If remove failed. + */ + public boolean removeAtomicReference(String name) throws IgniteCheckedException; + + /** + * Will get a atomic stamped from cache and create one if it has not been created yet and {@code create} flag + * is {@code true}. + * + * @param name Atomic stamped name. + * @param initVal Initial value for atomic stamped. If atomic stamped already cached, + * {@code initVal} will be ignored. + * @param initStamp Initial stamp for atomic stamped. If atomic stamped already cached, + * {@code initStamp} will be ignored. + * @param create Boolean flag indicating whether data structure should be created if does not exist. + * @return Atomic stamped for the given name. + * @throws IgniteCheckedException If atomic stamped could not be fetched or created. + */ + @Nullable public <T, S> GridCacheAtomicStamped<T, S> atomicStamped(String name, @Nullable T initVal, + @Nullable S initStamp, boolean create) throws IgniteCheckedException; + + /** + * Remove atomic stamped from cache. + * + * @param name Atomic stamped name. + * @return {@code True} if atomic stamped has been removed, {@code false} otherwise. + * @throws IgniteCheckedException If remove failed. + */ + public boolean removeAtomicStamped(String name) throws IgniteCheckedException; + + /** + * Gets or creates count down latch. If count down latch is not found in cache and {@code create} flag + * is {@code true}, it is created using provided name and count parameter. + * + * @param name Name of the latch. + * @param cnt Count for new latch creation. + * @param autoDel {@code True} to automatically delete latch from cache + * when its count reaches zero. + * @param create Boolean flag indicating whether data structure should be created if does not exist. + * @return Count down latch for the given name. + * @throws IgniteCheckedException If operation failed. + */ + @Nullable public GridCacheCountDownLatch countDownLatch(String name, int cnt, boolean autoDel, boolean create) + throws IgniteCheckedException; + + /** + * Removes count down latch from cache. + * + * @param name Name of the latch. + * @return Count down latch for the given name. + * @throws IgniteCheckedException If operation failed. + */ + public boolean removeCountDownLatch(String name) throws IgniteCheckedException; +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheQueue.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheQueue.java b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheQueue.java new file mode 100644 index 0000000..9636338 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheQueue.java @@ -0,0 +1,182 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.datastructures; + +import org.apache.ignite.*; +import org.jetbrains.annotations.*; + +import java.util.*; +import java.util.concurrent.*; + +/** + * This interface provides a rich API for working with distributed queues based on In-Memory Data Grid. + * <p> + * <h1 class="header">Overview</h1> + * Cache queue provides an access to cache elements using typical queue API. Cache queue also implements + * {@link Collection} interface and provides all methods from collections including + * {@link Collection#addAll(Collection)}, {@link Collection#removeAll(Collection)}, and + * {@link Collection#retainAll(Collection)} methods for bulk operations. Note that all + * {@link Collection} methods in the queue may throw {@link IgniteException} in case + * of failure. + * <p> + * All queue operations have synchronous and asynchronous counterparts. + * <h1 class="header">Bounded vs Unbounded</h1> + * Queues can be {@code unbounded} or {@code bounded}. {@code Bounded} queues can + * have maximum capacity. Queue capacity can be set at creation time and cannot be + * changed later. Here is an example of how to create {@code bounded} {@code LIFO} queue with + * capacity of {@code 1000} items. + * <pre name="code" class="java"> + * GridCacheQueue<String> queue = cache().queue("anyName", LIFO, 1000); + * ... + * queue.add("item"); + * </pre> + * For {@code bounded} queues <b>blocking</b> operations, such as {@link #take()} or {@link #put(Object)} + * are available. These operations will block until queue capacity changes to make the operation + * possible. + * <h1 class="header">Collocated vs Non-collocated</h1> + * Queue items can be placed on one node or distributed throughout grid nodes + * (governed by {@code collocated} parameter). {@code Non-collocated} mode is provided only + * for partitioned caches. If {@code collocated} parameter is {@code true}, then all queue items + * will be collocated on one node, otherwise items will be distributed through all grid nodes. + * Unless explicitly specified, by default queues are {@code collocated}. + * <p> + * Here is an example of how create {@code unbounded} queue + * in non-collocated mode. + * <pre name="code" class="java"> + * GridCacheQueue<String> queue = cache().queue("anyName", 0 /*unbounded*/, false /*non-collocated*/); + * ... + * queue.add("item"); + * </pre> + * <h1 class="header">Creating Cache Queues</h1> + * Instances of distributed cache queues can be created by calling the following method + * on {@link GridCacheDataStructures} API: + * <ul> + * <li>{@link GridCacheDataStructures#queue(String, int, boolean, boolean)}</li> + * </ul> + * @see GridCacheDataStructures#queue(String, int, boolean, boolean) + * @see GridCacheDataStructures#removeQueue(String) + * @see GridCacheDataStructures#removeQueue(String, int) + */ +public interface GridCacheQueue<T> extends BlockingQueue<T> { + /** + * Gets queue name. + * + * @return Queue name. + */ + public String name(); + + /** {@inheritDoc} */ + @Override public boolean add(T item) throws IgniteException; + + /** {@inheritDoc} */ + @Override public boolean offer(T item) throws IgniteException; + + /** {@inheritDoc} */ + @Override public boolean offer(T item, long timeout, TimeUnit unit) throws IgniteException; + + /** {@inheritDoc} */ + @Override public boolean addAll(Collection<? extends T> items) throws IgniteException; + + /** {@inheritDoc} */ + @Override public boolean contains(Object item) throws IgniteException; + + /** {@inheritDoc} */ + @Override public boolean containsAll(Collection<?> items) throws IgniteException; + + /** {@inheritDoc} */ + @Override public void clear() throws IgniteException; + + /** {@inheritDoc} */ + @Override public boolean remove(Object item) throws IgniteException; + + /** {@inheritDoc} */ + @Override public boolean removeAll(Collection<?> items) throws IgniteException; + + /** {@inheritDoc} */ + @Override public boolean isEmpty() throws IgniteException; + + /** {@inheritDoc} */ + @Override public Iterator<T> iterator() throws IgniteException; + + /** {@inheritDoc} */ + @Override public Object[] toArray() throws IgniteException; + + /** {@inheritDoc} */ + @Override public <T> T[] toArray(T[] a) throws IgniteException; + + /** {@inheritDoc} */ + @Override public boolean retainAll(Collection<?> items) throws IgniteException; + + /** {@inheritDoc} */ + @Override public int size() throws IgniteException; + + /** {@inheritDoc} */ + @Override @Nullable public T poll() throws IgniteException; + + /** {@inheritDoc} */ + @Override @Nullable public T peek() throws IgniteException; + + /** {@inheritDoc} */ + @Override public void put(T item) throws IgniteException; + + /** {@inheritDoc} */ + @Override @Nullable public T take() throws IgniteException; + + /** {@inheritDoc} */ + @Override @Nullable public T poll(long timeout, TimeUnit unit) throws IgniteException; + + /** + * Removes all of the elements from this queue. Method is used in massive queues with huge numbers of elements. + * + * @param batchSize Batch size. + * @throws IgniteException if operation failed. + */ + public void clear(int batchSize) throws IgniteException; + + /** + * Gets maximum number of elements of the queue. + * + * @return Maximum number of elements. If queue is unbounded {@code Integer.MAX_SIZE} will return. + * @throws IgniteCheckedException If operation failed. + */ + public int capacity() throws IgniteCheckedException; + + /** + * Returns {@code true} if this queue is bounded. + * + * @return {@code true} if this queue is bounded. + * @throws IgniteCheckedException If operation failed. + */ + public boolean bounded() throws IgniteCheckedException; + + /** + * Returns {@code true} if this queue can be kept on the one node only. + * Returns {@code false} if this queue can be kept on the many nodes. + * + * @return {@code true} if this queue is in {@code collocated} mode {@code false} otherwise. + * @throws IgniteCheckedException If operation failed. + */ + public boolean collocated() throws IgniteCheckedException; + + /** + * Gets status of queue. + * + * @return {@code true} if queue was removed from cache {@code false} otherwise. + */ + public boolean removed(); +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheSet.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheSet.java b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheSet.java new file mode 100644 index 0000000..37f7c80 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/GridCacheSet.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.datastructures; + +import org.apache.ignite.*; + +import java.util.*; + +/** + * Set implementation based on on In-Memory Data Grid. + * <h1 class="header">Overview</h1> + * Cache set implements {@link Set} interface and provides all methods from collections. + * Note that all {@link Collection} methods in the set may throw {@link IgniteException} in case of failure + * or if set was removed. + * <h1 class="header">Collocated vs Non-collocated</h1> + * Set items can be placed on one node or distributed throughout grid nodes + * (governed by {@code collocated} parameter). {@code Non-collocated} mode is provided only + * for partitioned caches. If {@code collocated} parameter is {@code true}, then all set items + * will be collocated on one node, otherwise items will be distributed through all grid nodes. + * @see GridCacheDataStructures#set(String, boolean, boolean) + * @see GridCacheDataStructures#removeSet(String) + */ +public interface GridCacheSet<T> extends Set<T> { + /** + * Gets set name. + * + * @return Set name. + */ + public String name(); + + /** + * Returns {@code true} if this set can be kept on the one node only. + * Returns {@code false} if this set can be kept on the many nodes. + * + * @return {@code True} if this set is in {@code collocated} mode {@code false} otherwise. + * @throws IgniteCheckedException If operation failed. + */ + public boolean collocated() throws IgniteCheckedException; + + /** + * Gets status of set. + * + * @return {@code True} if set was removed from cache {@code false} otherwise. + */ + public boolean removed(); +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/datastructures/package.html ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/datastructures/package.html b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/package.html new file mode 100644 index 0000000..af7bc37 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/datastructures/package.html @@ -0,0 +1,24 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. + --> + +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<body> + <!-- Package description. --> + Contains distributed data structures that work on top of in-memory data grid. +</body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/eviction/EvictableEntry.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/EvictableEntry.java b/modules/core/src/main/java/org/apache/ignite/cache/eviction/EvictableEntry.java index 4b244ba..ce5fb82 100644 --- a/modules/core/src/main/java/org/apache/ignite/cache/eviction/EvictableEntry.java +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/EvictableEntry.java @@ -22,7 +22,7 @@ import org.jetbrains.annotations.*; import javax.cache.*; /** - * Evictable cache entry passed into {@link org.gridgain.grid.cache.eviction.GridCacheEvictionPolicy}. + * Evictable cache entry passed into {@link org.apache.ignite.cache.eviction.GridCacheEvictionPolicy}. * * @author @java.author * @version @java.version http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/eviction/GridCacheEvictionFilter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/GridCacheEvictionFilter.java b/modules/core/src/main/java/org/apache/ignite/cache/eviction/GridCacheEvictionFilter.java new file mode 100644 index 0000000..4dca249 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/GridCacheEvictionFilter.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.eviction; + +import org.apache.ignite.cache.*; +import org.gridgain.grid.cache.*; + +/** + * Eviction filter to specify which entries should not be evicted. Not applicable when + * calling explicit evict via {@link org.apache.ignite.cache.GridCacheEntry#evict()}. + * If {@link #evictAllowed(org.apache.ignite.cache.GridCacheEntry)} method returns {@code false} then eviction + * policy will not be notified and entry will never be evicted. + * <p> + * Eviction filter can be configured via {@link CacheConfiguration#getEvictionFilter()} + * configuration property. Default value is {@code null} which means that all + * cache entries will be tracked by eviction policy. + */ +public interface GridCacheEvictionFilter<K, V> { + /** + * Checks if entry may be evicted from cache. + * + * @param entry Cache entry. + * @return {@code True} if it is allowed to evict this entry. + */ + public boolean evictAllowed(GridCacheEntry<K, V> entry); +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/eviction/GridCacheEvictionPolicy.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/GridCacheEvictionPolicy.java b/modules/core/src/main/java/org/apache/ignite/cache/eviction/GridCacheEvictionPolicy.java new file mode 100644 index 0000000..719caee --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/GridCacheEvictionPolicy.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.eviction; + +import org.apache.ignite.cache.*; +import org.gridgain.grid.cache.*; + +/** + * Pluggable cache eviction policy. Usually, implementations will internally order + * cache entries based on {@link #onEntryAccessed(boolean, org.apache.ignite.cache.GridCacheEntry)} notifications and + * whenever an element needs to be evicted, {@link org.apache.ignite.cache.GridCacheEntry#evict()} + * method should be called. If you need to access the underlying cache directly + * from this policy, you can get it via {@link org.apache.ignite.cache.GridCacheEntry#projection()} method. + * <p> + * GridGain comes with following eviction policies out-of-the-box: + * <ul> + * <li>{@link org.apache.ignite.cache.eviction.lru.GridCacheLruEvictionPolicy}</li> + * <li>{@link org.apache.ignite.cache.eviction.random.GridCacheRandomEvictionPolicy}</li> + * <li>{@link org.apache.ignite.cache.eviction.fifo.GridCacheFifoEvictionPolicy}</li> + * </ul> + * <p> + * The eviction policy thread-safety is ensured by GridGain. Implementations of this interface should + * not worry about concurrency and should be implemented as they were only accessed from one thread. + * <p> + * Note that implementations of all eviction policies provided by GridGain are very + * light weight in a way that they are all lock-free (or very close to it), and do not + * create any internal tables, arrays, or other expensive structures. + * The eviction order is preserved by attaching light-weight meta-data to existing + * cache entries. + */ +public interface GridCacheEvictionPolicy<K, V> { + /** + * Callback for whenever entry is accessed. + * + * @param rmv {@code True} if entry has been removed, {@code false} otherwise. + * @param entry Accessed entry. + */ + public void onEntryAccessed(boolean rmv, GridCacheEntry<K, V> entry); +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/eviction/fifo/GridCacheFifoEvictionPolicy.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/fifo/GridCacheFifoEvictionPolicy.java b/modules/core/src/main/java/org/apache/ignite/cache/eviction/fifo/GridCacheFifoEvictionPolicy.java new file mode 100644 index 0000000..b57deb4 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/fifo/GridCacheFifoEvictionPolicy.java @@ -0,0 +1,209 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.eviction.fifo; + +import org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.eviction.*; +import org.gridgain.grid.cache.*; +import org.jdk8.backport.*; +import org.jdk8.backport.ConcurrentLinkedDeque8.*; +import org.gridgain.grid.util.typedef.*; +import org.gridgain.grid.util.typedef.internal.*; + +import java.util.*; + +/** + * Eviction policy based on {@code First In First Out (FIFO)} algorithm. This + * implementation is very efficient since it does not create any additional + * table-like data structures. The {@code FIFO} ordering information is + * maintained by attaching ordering metadata to cache entries. + */ +public class GridCacheFifoEvictionPolicy<K, V> implements GridCacheEvictionPolicy<K, V>, + GridCacheFifoEvictionPolicyMBean { + /** Tag. */ + private final String meta = UUID.randomUUID().toString(); + + /** Maximum size. */ + private volatile int max = CacheConfiguration.DFLT_CACHE_SIZE; + + /** FIFO queue. */ + private final ConcurrentLinkedDeque8<GridCacheEntry<K, V>> queue = + new ConcurrentLinkedDeque8<>(); + + /** + * Constructs FIFO eviction policy with all defaults. + */ + public GridCacheFifoEvictionPolicy() { + // No-op. + } + + /** + * Constructs FIFO eviction policy with maximum size. Empty entries are allowed. + * + * @param max Maximum allowed size of cache before entry will start getting evicted. + */ + public GridCacheFifoEvictionPolicy(int max) { + A.ensure(max > 0, "max > 0"); + + this.max = max; + } + + /** + * Gets maximum allowed size of cache before entry will start getting evicted. + * + * @return Maximum allowed size of cache before entry will start getting evicted. + */ + @Override public int getMaxSize() { + return max; + } + + /** + * Sets maximum allowed size of cache before entry will start getting evicted. + * + * @param max Maximum allowed size of cache before entry will start getting evicted. + */ + @Override public void setMaxSize(int max) { + A.ensure(max > 0, "max > 0"); + + this.max = max; + } + + /** {@inheritDoc} */ + @Override public int getCurrentSize() { + return queue.size(); + } + + /** {@inheritDoc} */ + @Override public String getMetaAttributeName() { + return meta; + } + + /** + * Gets read-only view on internal {@code FIFO} queue in proper order. + * + * @return Read-only view ono internal {@code 'FIFO'} queue. + */ + public Collection<GridCacheEntry<K, V>> queue() { + return Collections.unmodifiableCollection(queue); + } + + /** {@inheritDoc} */ + @Override public void onEntryAccessed(boolean rmv, GridCacheEntry<K, V> entry) { + if (!rmv) { + if (!entry.isCached()) + return; + + // Shrink only if queue was changed. + if (touch(entry)) + shrink(); + } + else { + Node<GridCacheEntry<K, V>> node = entry.removeMeta(meta); + + if (node != null) + queue.unlinkx(node); + } + } + + /** + * @param entry Entry to touch. + * @return {@code True} if queue has been changed by this call. + */ + private boolean touch(GridCacheEntry<K, V> entry) { + Node<GridCacheEntry<K, V>> node = entry.meta(meta); + + // Entry has not been enqueued yet. + if (node == null) { + while (true) { + node = queue.offerLastx(entry); + + if (entry.putMetaIfAbsent(meta, node) != null) { + // Was concurrently added, need to clear it from queue. + queue.unlinkx(node); + + // Queue has not been changed. + return false; + } + else if (node.item() != null) { + if (!entry.isCached()) { + // Was concurrently evicted, need to clear it from queue. + queue.unlinkx(node); + + return false; + } + + return true; + } + // If node was unlinked by concurrent shrink() call, we must repeat the whole cycle. + else if (!entry.removeMeta(meta, node)) + return false; + } + } + + // Entry is already in queue. + return false; + } + + /** + * Shrinks FIFO queue to maximum allowed size. + */ + private void shrink() { + int max = this.max; + + int startSize = queue.sizex(); + + for (int i = 0; i < startSize && queue.sizex() > max; i++) { + GridCacheEntry<K, V> entry = queue.poll(); + + if (entry == null) + break; + + if (!entry.evict()) { + entry.removeMeta(meta); + + touch(entry); + } + } + } + + /** + * Checks entry for empty value. + * + * @param entry Entry to check. + * @return {@code True} if entry is empty. + */ + private boolean empty(GridCacheEntry<K, V> entry) { + try { + return entry.peek(F.asList(GridCachePeekMode.GLOBAL)) == null; + } + catch (IgniteCheckedException e) { + U.error(null, e.getMessage(), e); + + assert false : "Should never happen: " + e; + + return false; + } + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(GridCacheFifoEvictionPolicy.class, this); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/eviction/fifo/GridCacheFifoEvictionPolicyMBean.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/fifo/GridCacheFifoEvictionPolicyMBean.java b/modules/core/src/main/java/org/apache/ignite/cache/eviction/fifo/GridCacheFifoEvictionPolicyMBean.java new file mode 100644 index 0000000..a330cad --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/fifo/GridCacheFifoEvictionPolicyMBean.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.eviction.fifo; + +import org.apache.ignite.mbean.*; + +/** + * MBean for {@code FIFO} eviction policy. + */ +@IgniteMBeanDescription("MBean for FIFO cache eviction policy.") +public interface GridCacheFifoEvictionPolicyMBean { + /** + * Gets name of metadata attribute used to store eviction policy data. + * + * @return Name of metadata attribute used to store eviction policy data. + */ + @IgniteMBeanDescription("Name of metadata attribute used to store eviction policy data.") + public String getMetaAttributeName(); + + /** + * Gets maximum allowed cache size. + * + * @return Maximum allowed cache size. + */ + @IgniteMBeanDescription("Maximum allowed cache size.") + public int getMaxSize(); + + /** + * Sets maximum allowed cache size. + * + * @param max Maximum allowed cache size. + */ + @IgniteMBeanDescription("Set maximum allowed cache size.") + public void setMaxSize(int max); + + /** + * Gets current queue size. + * + * @return Current queue size. + */ + @IgniteMBeanDescription("Current FIFO queue size.") + public int getCurrentSize(); +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/eviction/fifo/package.html ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/fifo/package.html b/modules/core/src/main/java/org/apache/ignite/cache/eviction/fifo/package.html new file mode 100644 index 0000000..a9bf047 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/fifo/package.html @@ -0,0 +1,23 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. + --> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<body> + <!-- Package description. --> + Contains cache FIFO eviction policy implementations. +</body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/GridCacheGgfsEvictionFilter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/GridCacheGgfsEvictionFilter.java b/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/GridCacheGgfsEvictionFilter.java new file mode 100644 index 0000000..a2c6a1c --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/GridCacheGgfsEvictionFilter.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.eviction.ggfs; + +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.eviction.*; +import org.gridgain.grid.cache.*; +import org.gridgain.grid.kernal.processors.ggfs.*; + +/** + * GGFS eviction filter which will not evict blocks of particular files. + */ +public class GridCacheGgfsEvictionFilter implements GridCacheEvictionFilter { + /** {@inheritDoc} */ + @Override public boolean evictAllowed(GridCacheEntry entry) { + Object key = entry.getKey(); + + return !(key instanceof GridGgfsBlockKey && ((GridGgfsBlockKey)key).evictExclude()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/GridCacheGgfsPerBlockLruEvictionPolicy.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/GridCacheGgfsPerBlockLruEvictionPolicy.java b/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/GridCacheGgfsPerBlockLruEvictionPolicy.java new file mode 100644 index 0000000..5a1d7d3 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/GridCacheGgfsPerBlockLruEvictionPolicy.java @@ -0,0 +1,354 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.eviction.ggfs; + +import org.apache.ignite.*; +import org.apache.ignite.cache.*; +import org.apache.ignite.cache.eviction.*; +import org.apache.ignite.fs.*; +import org.gridgain.grid.cache.*; +import org.gridgain.grid.kernal.processors.ggfs.*; +import org.jdk8.backport.*; +import org.jdk8.backport.ConcurrentLinkedDeque8.*; +import org.jetbrains.annotations.*; + +import java.util.*; +import java.util.concurrent.atomic.*; +import java.util.regex.*; + +/** + * GGFS eviction policy which evicts particular blocks. + */ +public class GridCacheGgfsPerBlockLruEvictionPolicy implements GridCacheEvictionPolicy<GridGgfsBlockKey, byte[]>, + GridCacheGgfsPerBlockLruEvictionPolicyMBean { + /** Meta denoting node in the queue. */ + public static final String META_NODE = "ggfs_node"; + + /** Maximum size. When reached, eviction begins. */ + private volatile long maxSize; + + /** Maximum amount of blocks. When reached, eviction begins. */ + private volatile int maxBlocks; + + /** Collection of regex for paths which must not be evicted. */ + private volatile Collection<String> excludePaths; + + /** Exclusion patterns. */ + private volatile Collection<Pattern> excludePatterns; + + /** Whether patterns must be recompiled during the next call. */ + private final AtomicBoolean excludeRecompile = new AtomicBoolean(true); + + /** Queue. */ + private final ConcurrentLinkedDeque8<GridCacheEntry<GridGgfsBlockKey, byte[]>> queue = + new ConcurrentLinkedDeque8<>(); + + /** Current size of all enqueued blocks in bytes. */ + private final LongAdder curSize = new LongAdder(); + + /** + * Default constructor. + */ + public GridCacheGgfsPerBlockLruEvictionPolicy() { + // No-op. + } + + /** + * Constructor. + * + * @param maxSize Maximum size. When reached, eviction begins. + * @param maxBlocks Maximum amount of blocks. When reached, eviction begins. + */ + public GridCacheGgfsPerBlockLruEvictionPolicy(long maxSize, int maxBlocks) { + this(maxSize, maxBlocks, null); + } + + /** + * Constructor. + * + * @param maxSize Maximum size. When reached, eviction begins. + * @param maxBlocks Maximum amount of blocks. When reached, eviction begins. + * @param excludePaths Collection of regex for path which must not be evicted. + */ + public GridCacheGgfsPerBlockLruEvictionPolicy(long maxSize, int maxBlocks, + @Nullable Collection<String> excludePaths) { + this.maxSize = maxSize; + this.maxBlocks = maxBlocks; + this.excludePaths = excludePaths; + } + + /** {@inheritDoc} */ + @Override public void onEntryAccessed(boolean rmv, GridCacheEntry<GridGgfsBlockKey, byte[]> entry) { + if (!rmv) { + if (!entry.isCached()) + return; + + if (touch(entry)) + shrink(); + } + else { + MetaEntry meta = entry.removeMeta(META_NODE); + + if (meta != null && queue.unlinkx(meta.node())) + changeSize(-meta.size()); + } + } + + /** + * @param entry Entry to touch. + * @return {@code True} if new node has been added to queue by this call. + */ + private boolean touch(GridCacheEntry<GridGgfsBlockKey, byte[]> entry) { + byte[] val = entry.peek(); + + int blockSize = val != null ? val.length : 0; + + MetaEntry meta = entry.meta(META_NODE); + + // Entry has not been enqueued yet. + if (meta == null) { + while (true) { + Node<GridCacheEntry<GridGgfsBlockKey, byte[]>> node = queue.offerLastx(entry); + + meta = new MetaEntry(node, blockSize); + + if (entry.putMetaIfAbsent(META_NODE, meta) != null) { + // Was concurrently added, need to clear it from queue. + queue.unlinkx(node); + + // Queue has not been changed. + return false; + } + else if (node.item() != null) { + if (!entry.isCached()) { + // Was concurrently evicted, need to clear it from queue. + queue.unlinkx(node); + + return false; + } + + // Increment current size. + changeSize(blockSize); + + return true; + } + // If node was unlinked by concurrent shrink() call, we must repeat the whole cycle. + else if (!entry.removeMeta(META_NODE, node)) + return false; + } + } + else { + int oldBlockSize = meta.size(); + + Node<GridCacheEntry<GridGgfsBlockKey, byte[]>> node = meta.node(); + + if (queue.unlinkx(node)) { + // Move node to tail. + Node<GridCacheEntry<GridGgfsBlockKey, byte[]>> newNode = queue.offerLastx(entry); + + int delta = blockSize - oldBlockSize; + + if (!entry.replaceMeta(META_NODE, meta, new MetaEntry(newNode, blockSize))) { + // Was concurrently added, need to clear it from queue. + if (queue.unlinkx(newNode)) + delta -= blockSize; + } + + if (delta != 0) { + changeSize(delta); + + if (delta > 0) + // Total size increased, so shrinking could be needed. + return true; + } + } + } + + // Entry is already in queue. + return false; + } + + /** + * Shrinks queue to maximum allowed size. + */ + private void shrink() { + long maxSize = this.maxSize; + int maxBlocks = this.maxBlocks; + + int cnt = queue.sizex(); + + for (int i = 0; i < cnt && (maxBlocks > 0 && queue.sizex() > maxBlocks || + maxSize > 0 && curSize.longValue() > maxSize); i++) { + GridCacheEntry<GridGgfsBlockKey, byte[]> entry = queue.poll(); + + if (entry == null) + break; // Queue is empty. + + byte[] val = entry.peek(); + + if (val != null) + changeSize(-val.length); // Change current size as we polled entry from the queue. + + if (!entry.evict()) { + // Reorder entries which we failed to evict. + entry.removeMeta(META_NODE); + + touch(entry); + } + } + } + + /** + * Change current size. + * + * @param delta Delta in bytes. + */ + private void changeSize(int delta) { + if (delta != 0) + curSize.add(delta); + } + + /** {@inheritDoc} */ + @Override public long getMaxSize() { + return maxSize; + } + + /** {@inheritDoc} */ + @Override public void setMaxSize(long maxSize) { + this.maxSize = maxSize; + } + + /** {@inheritDoc} */ + @Override public int getMaxBlocks() { + return maxBlocks; + } + + /** {@inheritDoc} */ + @Override public void setMaxBlocks(int maxBlocks) { + this.maxBlocks = maxBlocks; + } + + /** {@inheritDoc} */ + @Override public Collection<String> getExcludePaths() { + return Collections.unmodifiableCollection(excludePaths); + } + + /** {@inheritDoc} */ + @Override public void setExcludePaths(@Nullable Collection<String> excludePaths) { + this.excludePaths = excludePaths; + + excludeRecompile.set(true); + } + + /** {@inheritDoc} */ + @Override public long getCurrentSize() { + return curSize.longValue(); + } + + /** {@inheritDoc} */ + @Override public int getCurrentBlocks() { + return queue.size(); + } + + /** + * Check whether provided path must be excluded from evictions. + * + * @param path Path. + * @return {@code True} in case non block of related file must be excluded. + * @throws IgniteCheckedException In case of faulty patterns. + */ + public boolean exclude(IgniteFsPath path) throws IgniteCheckedException { + assert path != null; + + Collection<Pattern> excludePatterns0; + + if (excludeRecompile.compareAndSet(true, false)) { + // Recompile. + Collection<String> excludePaths0 = excludePaths; + + if (excludePaths0 != null) { + excludePatterns0 = new HashSet<>(excludePaths0.size(), 1.0f); + + for (String excludePath : excludePaths0) { + try { + excludePatterns0.add(Pattern.compile(excludePath)); + } + catch (PatternSyntaxException ignore) { + throw new IgniteCheckedException("Invalid regex pattern: " + excludePath); + } + } + + excludePatterns = excludePatterns0; + } + else + excludePatterns0 = excludePatterns = null; + } + else + excludePatterns0 = excludePatterns; + + if (excludePatterns0 != null) { + String pathStr = path.toString(); + + for (Pattern pattern : excludePatterns0) { + if (pattern.matcher(pathStr).matches()) + return true; + } + } + + return false; + } + + /** + * Meta entry. + */ + private static class MetaEntry { + /** Queue node. */ + private final Node<GridCacheEntry<GridGgfsBlockKey, byte[]>> node; + + /** Data size. */ + private final int size; + + /** + * Constructor. + * + * @param node Queue node. + * @param size Data size. + */ + private MetaEntry(Node<GridCacheEntry<GridGgfsBlockKey, byte[]>> node, int size) { + assert node != null; + assert size >= 0; + + this.node = node; + this.size = size; + } + + /** + * @return Queue node. + */ + private Node<GridCacheEntry<GridGgfsBlockKey, byte[]>> node() { + return node; + } + + /** + * @return Data size. + */ + private int size() { + return size; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/GridCacheGgfsPerBlockLruEvictionPolicyMBean.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/GridCacheGgfsPerBlockLruEvictionPolicyMBean.java b/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/GridCacheGgfsPerBlockLruEvictionPolicyMBean.java new file mode 100644 index 0000000..994a227 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/GridCacheGgfsPerBlockLruEvictionPolicyMBean.java @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.ignite.cache.eviction.ggfs; + +import org.apache.ignite.mbean.*; +import org.jetbrains.annotations.*; + +import java.util.*; + +/** + * MBean for {@code GGFS per-block LRU} eviction policy. + */ +@IgniteMBeanDescription("MBean for GGFS per-block LRU cache eviction policy.") +public interface GridCacheGgfsPerBlockLruEvictionPolicyMBean { + /** + * Gets maximum allowed size of all blocks in bytes. + * + * @return Maximum allowed size of all blocks in bytes. + */ + @IgniteMBeanDescription("Maximum allowed size of all blocks in bytes.") + public long getMaxSize(); + + /** + * Sets maximum allowed size of data in all blocks in bytes. + * + * @param maxSize Maximum allowed size of data in all blocks in bytes. + */ + @IgniteMBeanDescription("Sets aximum allowed size of data in all blocks in bytes.") + public void setMaxSize(long maxSize); + + /** + * Gets maximum allowed amount of blocks. + * + * @return Maximum allowed amount of blocks. + */ + @IgniteMBeanDescription("Maximum allowed amount of blocks.") + public int getMaxBlocks(); + + /** + * Sets maximum allowed amount of blocks. + * + * @param maxBlocks Maximum allowed amount of blocks. + */ + @IgniteMBeanDescription("Sets maximum allowed amount of blocks.") + public void setMaxBlocks(int maxBlocks); + + /** + * Gets collection of regex for paths whose blocks must not be evicted. + * + * @return Collection of regex for paths whose blocks must not be evicted. + */ + @IgniteMBeanDescription("Collection of regex for paths whose blocks must not be evicted.") + @Nullable public Collection<String> getExcludePaths(); + + /** + * Sets collection of regex for paths whose blocks must not be evicted. + * + * @param excludePaths Collection of regex for paths whose blocks must not be evicted. + */ + @IgniteMBeanDescription("Sets collection of regex for paths whose blocks must not be evicted.") + public void setExcludePaths(@Nullable Collection<String> excludePaths); + + /** + * Gets current size of data in all blocks. + * + * @return Current size of data in all blocks. + */ + @IgniteMBeanDescription("Current size of data in all blocks.") + public long getCurrentSize(); + + /** + * Gets current amount of blocks. + * + * @return Current amount of blocks. + */ + @IgniteMBeanDescription("Current amount of blocks.") + public int getCurrentBlocks(); +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/7b1a738d/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/package.html ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/package.html b/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/package.html new file mode 100644 index 0000000..7505d73 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/cache/eviction/ggfs/package.html @@ -0,0 +1,23 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. + --> +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<html> +<body> +<!-- Package description. --> +Contains GGFS LRU eviction policy implementations. +</body> +</html>