Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2008-2021, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.map.impl.querycache.accumulator;
import com.hazelcast.logging.ILogger;
import com.hazelcast.logging.Logger;
import com.hazelcast.map.impl.querycache.QueryCacheContext;
import com.hazelcast.map.impl.querycache.QueryCacheEventService;
import com.hazelcast.map.impl.querycache.event.QueryCacheEventData;
import com.hazelcast.map.impl.querycache.event.sequence.Sequenced;
import com.hazelcast.map.impl.querycache.publisher.EventPublisherAccumulatorProcessor;
import com.hazelcast.map.impl.querycache.publisher.PublisherAccumulatorHandler;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import static com.hazelcast.internal.util.Preconditions.checkNotNull;
/**
* This class implements basic functionality of an {@link Accumulator}.
* Subclasses should override required methods according to their context.
*
* @param the type which will be accumulated in this {@link Accumulator}.
* @see com.hazelcast.map.impl.querycache.publisher.NonStopPublisherAccumulator
* @see com.hazelcast.map.impl.querycache.publisher.BatchPublisherAccumulator
*/
public class BasicAccumulator extends AbstractAccumulator {
protected final AccumulatorHandler handler;
protected final ILogger logger = Logger.getLogger(getClass());
protected BasicAccumulator(QueryCacheContext context, AccumulatorInfo info) {
super(context, info);
this.handler = createAccumulatorHandler(context, info);
}
@Override
public void accumulate(E event) {
long sequence = partitionSequencer.nextSequence();
event.setSequence(sequence);
getBuffer().add(event);
}
@Override
public int poll(AccumulatorHandler handler, int maxItems) {
if (maxItems < 1) {
return 0;
}
CyclicBuffer buffer = getBuffer();
int size = size();
if (size < 1 || size < maxItems) {
return 0;
}
int count = 0;
do {
E current = buffer.getAndAdvance();
if (current == null) {
break;
}
count++;
handler.handle(current, count == maxItems);
} while (count < maxItems);
return count;
}
@Override
public int poll(AccumulatorHandler handler, long delay, TimeUnit unit) {
CyclicBuffer buffer = getBuffer();
if (size() < 1) {
return 0;
}
long now = getNow();
int count = 0;
E next;
do {
E current = readCurrentExpiredOrNull(now, delay, unit);
if (current == null) {
break;
}
next = readNextExpiredOrNull(now, delay, unit);
handler.handle(current, next == null);
count++;
buffer.getAndAdvance();
} while (next != null);
return count;
}
@Override
public Iterator iterator() {
CyclicBuffer buffer = getBuffer();
return new ReadOnlyIterator<>(buffer);
}
@Override
public int size() {
return buffer.size();
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public AccumulatorInfo getInfo() {
return info;
}
@Override
public boolean setHead(long sequence) {
return buffer.setHead(sequence);
}
@Override
public void reset() {
handler.reset();
super.reset();
}
private E readNextExpiredOrNull(long now, long delay, TimeUnit unit) {
long headSequence = buffer.getHeadSequence();
headSequence++;
E sequenced = buffer.get(headSequence);
if (sequenced == null) {
return null;
}
return isExpired((QueryCacheEventData) sequenced, unit.toMillis(delay), now) ? sequenced : null;
}
private E readCurrentExpiredOrNull(long now, long delay, TimeUnit unit) {
long headSequence = buffer.getHeadSequence();
E sequenced = buffer.get(headSequence);
if (sequenced == null) {
return null;
}
return isExpired((QueryCacheEventData) sequenced, unit.toMillis(delay), now) ? sequenced : null;
}
@SuppressWarnings("unchecked")
protected AccumulatorHandler createAccumulatorHandler(QueryCacheContext context, AccumulatorInfo info) {
QueryCacheEventService queryCacheEventService = context.getQueryCacheEventService();
AccumulatorProcessor processor = createAccumulatorProcessor(info, queryCacheEventService);
return (AccumulatorHandler) new PublisherAccumulatorHandler(context, processor);
}
protected AccumulatorProcessor createAccumulatorProcessor(AccumulatorInfo info,
QueryCacheEventService eventService) {
return new EventPublisherAccumulatorProcessor(info, eventService);
}
/**
* Iterator used to read an {@link Accumulator}.
*
* @param the type which can be stored in the {@link Accumulator}.
*/
static class ReadOnlyIterator implements Iterator {
private final CyclicBuffer buffer;
ReadOnlyIterator(CyclicBuffer buffer) {
this.buffer = checkNotNull(buffer, "buffer cannot be null");
}
@Override
public boolean hasNext() {
return buffer.size() > 0;
}
@Override
public T next() {
return buffer.getAndAdvance();
}
@Override
public void remove() {
throw new UnsupportedOperationException("Only read only iteration is allowed");
}
}
}