/*
* 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.internal.managers.indexing;
import java.util.Collection;
import java.util.Iterator;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.SkipDaemon;
import org.apache.ignite.internal.managers.GridManagerAdapter;
import org.apache.ignite.internal.util.GridEmptyCloseableIterator;
import org.apache.ignite.internal.util.GridSpinBusyLock;
import org.apache.ignite.spi.IgniteSpiCloseableIterator;
import org.apache.ignite.spi.IgniteSpiException;
import org.apache.ignite.spi.indexing.IndexingQueryFilter;
import org.apache.ignite.spi.indexing.IndexingSpi;
/**
* Manages cache indexing.
*/
@SkipDaemon
public class GridIndexingManager extends GridManagerAdapter<IndexingSpi> {
/** */
private final GridSpinBusyLock busyLock = new GridSpinBusyLock();
/**
* @param ctx Kernal context.
*/
public GridIndexingManager(GridKernalContext ctx) {
super(ctx, ctx.config().getIndexingSpi());
}
/**
* @throws IgniteCheckedException Thrown in case of any errors.
*/
@Override public void start(boolean activeOnStart) throws IgniteCheckedException {
startSpi();
if (log.isDebugEnabled())
log.debug(startInfo());
}
/** {@inheritDoc} */
@Override protected void onKernalStop0(boolean cancel) {
if (ctx.config().isDaemon())
return;
busyLock.block();
}
/**
* @throws IgniteCheckedException Thrown in case of any errors.
*/
@Override public void stop(boolean cancel) throws IgniteCheckedException {
if (ctx.config().isDaemon())
return;
stopSpi();
if (log.isDebugEnabled())
log.debug(stopInfo());
}
/**
* Writes key-value pair to index.
*
* @param space Space.
* @param key Key.
* @param val Value.
* @param expirationTime Expiration time or 0 if never expires.
* @throws IgniteCheckedException In case of error.
*/
@SuppressWarnings("unchecked")
public <K, V> void store(final String space, final K key, final V val, long expirationTime) throws IgniteCheckedException {
assert key != null;
assert val != null;
assert enabled();
if (!busyLock.enterBusy())
throw new IllegalStateException("Failed to write to index (grid is stopping).");
try {
if (log.isDebugEnabled())
log.debug("Storing key to cache query index [key=" + key + ", value=" + val + "]");
getSpi().store(space, key, val, expirationTime);
}
finally {
busyLock.leaveBusy();
}
}
/**
* @param space Space.
* @param key Key.
* @throws IgniteCheckedException Thrown in case of any errors.
*/
@SuppressWarnings("unchecked")
public void remove(String space, Object key) throws IgniteCheckedException {
assert key != null;
assert enabled();
if (!busyLock.enterBusy())
throw new IllegalStateException("Failed to remove from index (grid is stopping).");
try {
getSpi().remove(space, key);
}
finally {
busyLock.leaveBusy();
}
}
/**
* @param space Space.
* @param params Parameters collection.
* @param filters Filters.
* @return Query result.
* @throws IgniteCheckedException If failed.
*/
@SuppressWarnings("unchecked")
public IgniteSpiCloseableIterator<?> query(String space, Collection<Object> params, IndexingQueryFilter filters)
throws IgniteCheckedException {
if (!enabled())
throw new IgniteCheckedException("Indexing SPI is not configured.");
if (!busyLock.enterBusy())
throw new IllegalStateException("Failed to execute query (grid is stopping).");
try {
final Iterator<?> res = getSpi().query(space, params, filters);
if (res == null)
return new GridEmptyCloseableIterator<>();
return new IgniteSpiCloseableIterator<Object>() {
@Override public void close() throws IgniteCheckedException {
if (res instanceof AutoCloseable) {
try {
((AutoCloseable)res).close();
}
catch (Exception e) {
throw new IgniteCheckedException(e);
}
}
}
@Override public boolean hasNext() {
return res.hasNext();
}
@Override public Object next() {
return res.next();
}
@Override public void remove() {
throw new UnsupportedOperationException();
}
};
}
finally {
busyLock.leaveBusy();
}
}
}