Package krati.retention

Source Code of krati.retention.SimpleSnapshot

/*
* Copyright (c) 2010-2012 LinkedIn, Inc
*
* 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 krati.retention;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import krati.core.StoreConfig;
import krati.core.segment.SegmentFactory;
import krati.io.Serializer;
import krati.retention.clock.Clock;
import krati.retention.policy.RetentionPolicy;
import krati.store.ObjectStore;
import krati.store.factory.ObjectStoreFactory;
import krati.util.IndexedIterator;

/**
* SimpleSnapshot
*
* @version 0.4.2
* @author jwu
*
* <p>
* 08/10, 2011 - Created <br/>
* 10/11, 2011 - Added clockStoreFactory to constructor <br/>
* 11/16, 2011 - Put a limit on the number of events upon each call to method get <br/>
*/
class SimpleSnapshot<T> implements Retention<T>, RetentionFlushListener {
    private final static Logger _logger = Logger.getLogger(SimpleSnapshot.class);
   
    protected final int _id;
    protected final int _eventBatchSize;
    protected final StoreConfig _clockStoreConfig;
    protected final ObjectStore<T, Clock> _clockStore;
    protected volatile Clock _maxClock;
   
    public SimpleSnapshot(
            int id, File homeDir,
            int initialCapacity, int batchSize, int numSyncBatches,
            SegmentFactory storeSegmentFactory, int storeSegmentFileSizeMB,
            ObjectStoreFactory<T, Clock> clockStoreFactory,
            Serializer<T> eventValueSerializer, Serializer<Clock> eventClockSerializer) throws Exception {
        this._id = id;
        this._eventBatchSize = batchSize;
       
        // Create config
        _clockStoreConfig = new StoreConfig(homeDir, initialCapacity);
        _clockStoreConfig.setBatchSize(batchSize);
        _clockStoreConfig.setNumSyncBatches(numSyncBatches);
        _clockStoreConfig.setSegmentFactory(storeSegmentFactory);
        _clockStoreConfig.setSegmentFileSizeMB(storeSegmentFileSizeMB);
       
        // Create clock store
        _clockStore = clockStoreFactory.create(_clockStoreConfig, eventValueSerializer, eventClockSerializer);
       
        init();
        _logger.info("started");
    }
   
    protected void init() {}
   
    protected Logger getLogger() {
        return _logger;
    }
   
    @Override
    public int getId() {
        return _id;
    }
   
    @Override
    public long getOrigin() {
        return 0;
    }
   
    @Override
    public long getOffset() {
        return _clockStore.capacity();
    }
   
    @Override
    public Clock getMinClock() {
        return Clock.ZERO;
    }
   
    @Override
    public Clock getMaxClock() {
        return _maxClock;
    }
   
    @Override
    public Clock getClock(long offset) {
        return null;
    }
   
    @Override
    public int getBatchSize() {
        return _eventBatchSize;
    }
   
    @Override
    public RetentionPolicy getRetentionPolicy() {
        throw new UnsupportedOperationException();
    }
   
    @Override
    public Position getPosition() {
        throw new UnsupportedOperationException();
    }
   
    @Override
    public Position getPosition(Clock sinceClock) {
        throw new UnsupportedOperationException();
    }
   
    @Override
    public Position get(Position pos, List<Event<T>> list) {
        if(pos == null || !pos.isIndexed() || pos.getId() != _id) {
            return pos;
        }
       
        int index = pos.getIndex();
        IndexedIterator<Entry<T, Clock>> iter = _clockStore.iterator();
       
        try {
            iter.reset(index);
        } catch(ArrayIndexOutOfBoundsException e) {
            return new SimplePosition(_id, pos.getOffset(), pos.getClock());
        }
       
        Clock evtClock;
        Clock posClock = pos.getClock();
       
        int cnt = 0;
        int lastIndex = index;
        while(iter.hasNext()) {
            lastIndex = iter.index();
            Entry<T, Clock> e = iter.next();
           
            evtClock = e.getValue();
            if(posClock.beforeEqual(evtClock)) {
                list.add(new SimpleEvent<T>(e.getKey(), evtClock));
                cnt++;
            }
           
            if(cnt >= _eventBatchSize) {
                index = iter.index();
                if(lastIndex == index) {
                    while(iter.hasNext() && iter.index() == index) {
                        e = iter.next();
                       
                        evtClock = e.getValue();
                        if(posClock.beforeEqual(evtClock)) {
                            list.add(new SimpleEvent<T>(e.getKey(), evtClock));
                            cnt++;
                        }
                    }
                    index++;
                }
               
                // Exit loop when enough events are collected
                break;
            }
        }
       
        if(cnt > 0) {
            getLogger().info("Read[" + pos.getIndex() + "," + index + ") " + cnt);
        }
       
        return iter.hasNext() ?
                    new SimplePosition(_id, pos.getOffset(), index, pos.getClock()) :
                    new SimplePosition(_id, pos.getOffset(), pos.getClock());
    }
   
    @Override
    public synchronized boolean put(Event<T> event) throws Exception {
        if(_clockStore.put(event.getValue(), event.getClock())) {
            _maxClock = event.getClock();
            return true;
        }
        return false;
    }
   
    @Override
    public void beforeFlush(EventBatch<?> batch) throws IOException {
        _clockStore.persist();
    }
   
    @Override
    public void afterFlush(EventBatch<?> batch) throws IOException {}
   
    @Override
    public boolean isOpen() {
        return _clockStore.isOpen();
    }
   
    @Override
    public synchronized void open() throws IOException {
        if(!_clockStore.isOpen()) {
            _clockStore.open();
        }
    }
   
    @Override
    public synchronized void close() throws IOException {
        if(_clockStore.isOpen()) {
            _clockStore.close();
        }
    }
   
    @Override
    public void flush() throws IOException {
        _clockStore.persist();
    }
}
TOP

Related Classes of krati.retention.SimpleSnapshot

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.