use of org.apache.ignite.internal.processors.cache.GridCacheMapEntry in project ignite by apache.
the class GridDhtCacheAdapter method localEntriesIteratorEx.
/**
* @param primary If {@code true} includes primary entries.
* @param backup If {@code true} includes backup entries.
* @param topVer Specified affinity topology version.
* @return Local entries iterator.
*/
public Iterator<? extends GridCacheEntryEx> localEntriesIteratorEx(final boolean primary, final boolean backup, final AffinityTopologyVersion topVer) {
assert primary || backup;
if (primary && backup)
return entries().iterator();
else {
final Iterator<GridDhtLocalPartition> partIt = topology().currentLocalPartitions().iterator();
return new Iterator<GridCacheMapEntry>() {
private GridCacheMapEntry next;
private Iterator<GridCacheMapEntry> curIt;
{
advance();
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public GridCacheMapEntry next() {
if (next == null)
throw new NoSuchElementException();
GridCacheMapEntry e = next;
advance();
return e;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private void advance() {
next = null;
do {
if (curIt == null) {
while (partIt.hasNext()) {
GridDhtLocalPartition part = partIt.next();
if (primary == part.primary(topVer)) {
curIt = part.entries().iterator();
break;
}
}
}
if (curIt != null) {
if (curIt.hasNext()) {
next = curIt.next();
break;
} else
curIt = null;
}
} while (partIt.hasNext());
}
};
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheMapEntry in project ignite by apache.
the class GridCachePartitionedConcurrentMap method putEntryIfObsoleteOrAbsent.
/** {@inheritDoc} */
@Override
public GridCacheMapEntry putEntryIfObsoleteOrAbsent(AffinityTopologyVersion topVer, KeyCacheObject key, boolean create, boolean touch) {
while (true) {
GridDhtLocalPartition part = localPartition(key, topVer, create);
if (part == null)
return null;
GridCacheMapEntry res = part.putEntryIfObsoleteOrAbsent(topVer, key, create, touch);
if (res != null || !create)
return res;
// Otherwise partition was concurrently evicted and should be re-created on next iteration.
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheMapEntry in project ignite by apache.
the class GridDhtAtomicCache method unlockEntries.
/**
* Releases java-level locks on cache entries.
*
* @param locked Locked entries.
* @param topVer Topology version.
*/
private void unlockEntries(List<GridDhtCacheEntry> locked, AffinityTopologyVersion topVer) {
// Process deleted entries before locks release.
assert ctx.deferredDelete() : this;
// Entries to skip eviction manager notification for.
// Enqueue entries while holding locks.
Collection<KeyCacheObject> skip = null;
int size = locked.size();
try {
for (int i = 0; i < size; i++) {
GridCacheMapEntry entry = locked.get(i);
if (entry != null && entry.deleted()) {
if (skip == null)
skip = U.newHashSet(locked.size());
skip.add(entry.key());
}
}
} finally {
// That's why releasing locks in the finally block..
for (int i = 0; i < size; i++) {
GridCacheMapEntry entry = locked.get(i);
if (entry != null)
GridUnsafe.monitorExit(entry);
}
}
// Try evict partitions.
for (int i = 0; i < size; i++) {
GridDhtCacheEntry entry = locked.get(i);
if (entry != null)
entry.onUnlock();
}
ctx.shared().database().checkpointReadUnlock();
if (skip != null && skip.size() == size)
// Optimization.
return;
// Eviction manager will remove empty entries.
for (int i = 0; i < size; i++) {
GridCacheMapEntry entry = locked.get(i);
if (entry != null && (skip == null || !skip.contains(entry.key())))
ctx.evicts().touch(entry, topVer);
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheMapEntry in project ignite by apache.
the class GridDhtAtomicCache method lockEntries.
/**
* Acquires java-level locks on cache entries. Returns collection of locked entries.
*
* @param req Request with keys to lock.
* @param topVer Topology version to lock on.
* @return Collection of locked entries.
* @throws GridDhtInvalidPartitionException If entry does not belong to local node. If exception is thrown, locks
* are released.
*/
@SuppressWarnings("ForLoopReplaceableByForEach")
private List<GridDhtCacheEntry> lockEntries(GridNearAtomicAbstractUpdateRequest req, AffinityTopologyVersion topVer) throws GridDhtInvalidPartitionException {
ctx.shared().database().checkpointReadLock();
if (req.size() == 1) {
KeyCacheObject key = req.key(0);
while (true) {
GridDhtCacheEntry entry = entryExx(key, topVer);
GridUnsafe.monitorEnter(entry);
if (entry.obsolete())
GridUnsafe.monitorExit(entry);
else
return Collections.singletonList(entry);
}
} else {
List<GridDhtCacheEntry> locked = new ArrayList<>(req.size());
while (true) {
for (int i = 0; i < req.size(); i++) {
GridDhtCacheEntry entry = entryExx(req.key(i), topVer);
locked.add(entry);
}
boolean retry = false;
for (int i = 0; i < locked.size(); i++) {
GridCacheMapEntry entry = locked.get(i);
if (entry == null)
continue;
GridUnsafe.monitorEnter(entry);
if (entry.obsolete()) {
// Unlock all locked.
for (int j = 0; j <= i; j++) {
if (locked.get(j) != null)
GridUnsafe.monitorExit(locked.get(j));
}
// Clear entries.
locked.clear();
// Retry.
retry = true;
break;
}
}
if (!retry)
return locked;
}
}
}
use of org.apache.ignite.internal.processors.cache.GridCacheMapEntry in project ignite by apache.
the class GridCacheQueueCleanupSelfTest method testCleanup.
/**
* @throws Exception If failed.
*/
public void testCleanup() throws Exception {
IgniteQueue<Integer> queue = grid(0).queue(QUEUE_NAME1, 0, config(false));
GridCacheContext cctx = GridTestUtils.getFieldValue(queue, "cctx");
final String queueCacheName = cctx.name();
ClusterNode node = grid(0).affinity(queueCacheName).mapKeyToNode(new GridCacheQueueHeaderKey(QUEUE_NAME1));
final Ignite ignite = grid(0).localNode().equals(node) ? grid(1) : grid(0);
/*
assertNotNull(queue);
// Add/poll some items.
for (int i = 0; i < 500; i++)
queue.add(i);
for (int i = 0; i < 10; i++)
queue.poll();
assertTrue(!queue.isEmpty());
// Kill node containing queue header.
final String killGridName = node.attribute(IgniteNodeAttributes.ATTR_IGNITE_INSTANCE_NAME);
stopGrid(killGridName);
assertNull(((IgniteKernal)grid).cache(DEFAULT_CACHE_NAME).dataStructures().queue(QUEUE_NAME1, 0, false, false));
final AtomicBoolean stop = new AtomicBoolean(false);
GridFuture<?> fut1;
GridFuture<?> fut2;
try {
// Start threads using cache concurrently with cleanup thread.
fut1 = startAddPollThread(grid, stop, QUEUE_NAME1);
fut2 = startAddPollThread(grid, stop, QUEUE_NAME2);
U.sleep(3000); // Give some time for cleanup thread.
}
finally {
stop.set(true);
}
fut1.get();
fut2.get();
((IgniteKernal)grid).cache(DEFAULT_CACHE_NAME).dataStructures().removeQueue(QUEUE_NAME1);
((IgniteKernal)grid).cache(DEFAULT_CACHE_NAME).dataStructures().removeQueue(QUEUE_NAME2);
assertTrue(GridTestUtils.waitForCondition(new PAX() {
@Override public boolean applyx() {
for (int i = 0; i < gridCount(); i++) {
if (getTestIgniteInstanceName(i).equals(killGridName))
continue;
Iterator<GridCacheEntryEx<Object, Object>> entries =
((GridKernal)grid(i)).context().cache().internalCache(DEFAULT_CACHE_NAME).map().allEntries0().iterator();
if (entries.hasNext()) {
log.info("Found cache entries, will wait: " + entries.next());
return false;
}
}
return true;
}
}, 5000));
startGrid(killGridName);
// Create queue again.
queue = ((IgniteKernal)grid).cache(DEFAULT_CACHE_NAME).dataStructures().queue(QUEUE_NAME1, 0, false, true);
*/
assertEquals(0, queue.size());
for (int i = 0; i < 500; i++) queue.add(i);
assertEquals(500, queue.size());
// Remove queue and create queue with the same name.
queue.close();
queue = ignite.queue(QUEUE_NAME1, 0, config(false));
assertEquals(0, queue.size());
for (int i = 0; i < 500; i++) queue.add(i);
assertEquals(500, queue.size());
// Check that items of removed queue are removed, items of new queue not.
assertTrue(GridTestUtils.waitForCondition(new PAX() {
@SuppressWarnings("WhileLoopReplaceableByForEach")
@Override
public boolean applyx() {
int cnt = 0;
for (int i = 0; i < gridCount(); i++) {
GridCacheAdapter<Object, Object> cache = ((IgniteKernal) grid(i)).context().cache().internalCache(queueCacheName);
Iterator<GridCacheMapEntry> entries = cache.map().entries().iterator();
while (entries.hasNext()) {
cnt++;
entries.next();
}
}
if (cnt > 501) {
// 500 items + header.
log.info("Found more cache entries than expected, will wait: " + cnt);
return false;
}
return true;
}
}, 5000));
for (int i = 0; i < 500; i++) assertEquals((Integer) i, queue.poll());
}
Aggregations