Package proj.zoie.pair.impl

Source Code of proj.zoie.pair.impl.Pair$PairAdminMBean

package proj.zoie.pair.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import javax.management.NotCompliantMBeanException;
import javax.management.StandardMBean;

import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.IndexReader;

import proj.zoie.api.DefaultDirectoryManager;
import proj.zoie.api.DirectoryManager;
import proj.zoie.api.DirectoryManager.DIRECTORY_MODE;
import proj.zoie.api.IndexCopier;
import proj.zoie.api.Zoie;
import proj.zoie.api.ZoieException;
import proj.zoie.api.ZoieHealth;
import proj.zoie.api.ZoieMultiReader;
import proj.zoie.api.indexing.IndexReaderDecorator;
import proj.zoie.api.indexing.ZoieIndexableInterpreter;
import proj.zoie.impl.indexing.ZoieConfig;
import proj.zoie.impl.indexing.ZoieSystem;
import proj.zoie.impl.indexing.internal.IndexSignature;
import proj.zoie.mbean.ZoieAdminMBean;

public class Pair<R extends IndexReader, D> implements Zoie<R, D> {
  public static final Logger log = Logger.getLogger(Pair.class);

  private static final String COMMIT_FILE = "committed";

  private volatile boolean _running = false;

  private volatile Zoie<R, D> _zoieOne;
  private final Zoie<R, D> _zoieTwo; // The realtime zoie.

  private final File _zoieOneRoot;
  private final IndexCopier _indexCopier;
  private final ZoieIndexableInterpreter<D> _interpreter;
  private final IndexReaderDecorator<R> _decorator;
  private final ZoieConfig _zoieConfig;
  private final Map<IndexReader, ZoieRef> _activeReaders;

  public Pair(File zoieOneRoot, DIRECTORY_MODE dirMode, IndexCopier indexCopier,
      ZoieIndexableInterpreter<D> interpreter, IndexReaderDecorator<R> decorator,
      ZoieConfig zoieConfig, Zoie<R, D> zoieTwo) {
    _zoieOneRoot = zoieOneRoot;
    _indexCopier = indexCopier;
    _interpreter = interpreter;
    _decorator = decorator;
    _zoieConfig = zoieConfig;
    _zoieTwo = zoieTwo;
    _activeReaders = new HashMap<IndexReader, ZoieRef>();

    // Initialize zoieOne:
    if (_zoieOneRoot == null) {
      throw new IllegalArgumentException("zoieOneRoot cannot be null.");
    }
    if (_zoieOneRoot.exists()) {
      File[] files = _zoieOneRoot.listFiles();
      Arrays.sort(files);
      for (int i = files.length - 1; i >= 0; --i) {
        if (new File(files[i], COMMIT_FILE).exists()) {
          log.info("Found latest zoieOne index: " + files[i].getAbsolutePath());
          DirectoryManager dirMgr = new DefaultDirectoryManager(files[i], dirMode);
          _zoieOne = new ZoieSystem<R, D>(dirMgr, _interpreter, _decorator, _zoieConfig);
          break;
        }
      }
    }
  }

  @SuppressWarnings({ "unchecked", "rawtypes" })
  public synchronized boolean loadIndex(String src) {
    File dest = new File(_zoieOneRoot, String.valueOf(System.currentTimeMillis()));
    while (!dest.mkdirs()) {
      try {
        Thread.sleep(1);
      } catch (InterruptedException e) {
        // ignore
      }
      dest = new File(_zoieOneRoot, String.valueOf(System.currentTimeMillis()));
    }

    log.info("Copying " + src + " to " + dest.getAbsolutePath());

    if (!_indexCopier.copy(src, dest.getAbsolutePath())) return false;

    File directoryFile = new File(dest, DirectoryManager.INDEX_DIRECTORY);
    if (!directoryFile.exists()) {
      log.warn("index directory file not exists, creating a empty one.");
      IndexSignature sig = new IndexSignature(null);
      try {
        DefaultDirectoryManager.saveSignature(sig, directoryFile);
      } catch (IOException e) {
        log.error(e.getMessage(), e);
        return false;
      }
    }

    try {
      // Touch the commit file:
      OutputStream out = new FileOutputStream(new File(dest, COMMIT_FILE));
      out.close();
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      return false;
    }

    // offline line index is not moving, so MMAP should be the most efficient.
    DirectoryManager dirMgr = new DefaultDirectoryManager(dest, DIRECTORY_MODE.MMAP);
    Zoie<R, D> zoie = new ZoieSystem(dirMgr, _interpreter, _decorator, _zoieConfig);
    if (_running) zoie.start();

    if (_zoieOne != null) {
      final Zoie toBeShutdown = _zoieOne;
      _zoieOne = zoie;

      Timer cleanupTimer = new Timer();

      cleanupTimer.schedule(new TimerTask() {
        @Override
        public void run() {
          synchronized (_activeReaders) {
            for (ZoieRef z : _activeReaders.values()) {
              if (z.zoie == toBeShutdown) {
                log.info("Waiting for active readers...");
                return;
              }
            }
          }
          log.info("Shuting down old zoie...");
          toBeShutdown.shutdown();
          cancel();
        }
      }, 8000, 8000);
    }

    _zoieOne = zoie;

    return true;
  }

  @Override
  public void start() {
    _running = true;
    Zoie<R, D> zoieOne = _zoieOne;
    if (zoieOne != null) {
      zoieOne.start();
    }

    if (_zoieTwo != null) {
      _zoieTwo.start();
    }
  }

  @Override
  public void shutdown() {
    _running = false;
    Zoie<R, D> zoieOne = _zoieOne;
    if (zoieOne != null) {
      zoieOne.shutdown();
    }

    if (_zoieTwo != null) {
      _zoieTwo.shutdown();
    }
  }

  @Override
  public StandardMBean getStandardMBean(String name) {
    if (name.equals(PAIRADMIN)) {
      try {
        return new StandardMBean(getAdminMBean(), PairAdminMBean.class);
      } catch (NotCompliantMBeanException e) {
        log.info(e);
        return null;
      }
    }
    return null;
  }

  @Override
  public PairAdminMBean getAdminMBean() {
    return new MyPairAdmin();
  }

  public static String PAIRADMIN = "pair-admin";

  @Override
  public String[] getStandardMBeanNames() {
    return new String[] { PAIRADMIN };
  }

  public interface PairAdminMBean extends ZoieAdminMBean {
    boolean loadIndex(String src);
  }

  private class MyPairAdmin implements PairAdminMBean {

    @Override
    public boolean loadIndex(String src) {
      return Pair.this.loadIndex(src);
    }

    @Override
    public String getIndexDir() {
      return Pair.this._zoieOneRoot.getAbsolutePath();
    }

    @Override
    public boolean isRealtime() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean().isRealtime();

      return false;
    }

    @Override
    public long getBatchDelay() {
      return Pair.this._zoieConfig.getBatchDelay();
    }

    @Override
    public void setBatchDelay(long delay) {
      Pair.this._zoieConfig.setBatchDelay(delay);
      if (Pair.this._zoieOne != null) Pair.this._zoieOne.getAdminMBean().setBatchDelay(delay);
      if (Pair.this._zoieTwo != null) Pair.this._zoieTwo.getAdminMBean().setBatchDelay(delay);
    }

    @Override
    public int getBatchSize() {
      return Pair.this._zoieConfig.getBatchSize();
    }

    @Override
    public void setBatchSize(int batchSize) {
      Pair.this._zoieConfig.setBatchSize(batchSize);
      if (Pair.this._zoieOne != null) Pair.this._zoieOne.getAdminMBean().setBatchSize(batchSize);
      if (Pair.this._zoieTwo != null) Pair.this._zoieTwo.getAdminMBean().setBatchSize(batchSize);
    }

    @Override
    public Date getLastDiskIndexModifiedTime() {
      Date d1 = null, d2 = null;
      if (Pair.this._zoieTwo != null) d2 = Pair.this._zoieTwo.getAdminMBean()
          .getLastDiskIndexModifiedTime();

      d1 = Pair.this._zoieOne.getAdminMBean().getLastDiskIndexModifiedTime();

      if (d2 == null) return d1;
      else if (d1 == null) return d2;
      else if (d1.compareTo(d2) > 0) return d1;
      else return d2;
    }

    @Override
    public int getMaxBatchSize() {
      return Pair.this._zoieConfig.getMaxBatchSize();
    }

    @Override
    public void setMaxBatchSize(int maxBatchSize) {
      Pair.this._zoieConfig.setMaxBatchSize(maxBatchSize);
      if (Pair.this._zoieOne != null) Pair.this._zoieOne.getAdminMBean().setMaxBatchSize(
        maxBatchSize);
      if (Pair.this._zoieTwo != null) Pair.this._zoieTwo.getAdminMBean().setMaxBatchSize(
        maxBatchSize);
    }

    @Override
    public void setMergeFactor(int mergeFactor) {
      if (Pair.this._zoieOne != null) Pair.this._zoieOne.getAdminMBean()
          .setMergeFactor(mergeFactor);
      if (Pair.this._zoieTwo != null) Pair.this._zoieTwo.getAdminMBean()
          .setMergeFactor(mergeFactor);
    }

    @Override
    public int getMergeFactor() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean().getMergeFactor();

      return Pair.this._zoieOne.getAdminMBean().getMergeFactor();
    }

    @Override
    public int getRamAIndexSize() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean().getRamAIndexSize();

      return 0;
    }

    @Override
    public String getRamAVersion() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean().getRamAVersion();

      return null;
    }

    @Override
    public int getRamBIndexSize() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean().getRamBIndexSize();

      return 0;
    }

    @Override
    public String getRamBVersion() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean().getRamBVersion();

      return null;
    }

    @Override
    public String getDiskIndexerStatus() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean()
          .getDiskIndexerStatus();

      return Pair.this._zoieOne.getAdminMBean().getDiskIndexerStatus();
    }

    @Override
    public String getCurrentDiskVersion() throws IOException {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean()
          .getCurrentDiskVersion();

      return Pair.this._zoieOne.getAdminMBean().getCurrentDiskVersion();
    }

    @Override
    public void refreshDiskReader() throws IOException {
      if (Pair.this._zoieTwo != null) Pair.this._zoieTwo.getAdminMBean().refreshDiskReader();
      if (Pair.this._zoieOne != null) Pair.this._zoieOne.getAdminMBean().refreshDiskReader();
    }

    @Override
    public void flushToDiskIndex() throws ZoieException {
      if (Pair.this._zoieTwo != null) Pair.this._zoieTwo.getAdminMBean().flushToDiskIndex();
      if (Pair.this._zoieOne != null) Pair.this._zoieOne.getAdminMBean().flushToDiskIndex();
    }

    @Override
    public void flushToMemoryIndex() throws ZoieException {
      if (Pair.this._zoieTwo != null) Pair.this._zoieTwo.getAdminMBean().flushToMemoryIndex();
      if (Pair.this._zoieOne != null) Pair.this._zoieOne.getAdminMBean().flushToMemoryIndex();
    }

    @Override
    public int getMaxMergeDocs() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean().getMaxMergeDocs();

      return Pair.this._zoieOne.getAdminMBean().getMaxMergeDocs();
    }

    @Override
    public void setMaxMergeDocs(int maxMergeDocs) {
      if (Pair.this._zoieTwo != null) Pair.this._zoieTwo.getAdminMBean().setMaxMergeDocs(
        maxMergeDocs);
      if (Pair.this._zoieOne != null) Pair.this._zoieOne.getAdminMBean().setMaxMergeDocs(
        maxMergeDocs);
    }

    @Override
    public void setNumLargeSegments(int numLargeSegments) {
      if (Pair.this._zoieTwo != null) Pair.this._zoieTwo.getAdminMBean().setNumLargeSegments(
        numLargeSegments);
      if (Pair.this._zoieOne != null) Pair.this._zoieOne.getAdminMBean().setNumLargeSegments(
        numLargeSegments);
    }

    @Override
    public int getNumLargeSegments() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean()
          .getNumLargeSegments();

      return Pair.this._zoieOne.getAdminMBean().getNumLargeSegments();
    }

    @Override
    public void setMaxSmallSegments(int maxSmallSegments) {
      if (Pair.this._zoieTwo != null) Pair.this._zoieTwo.getAdminMBean().setMaxSmallSegments(
        maxSmallSegments);
      if (Pair.this._zoieOne != null) Pair.this._zoieOne.getAdminMBean().setMaxSmallSegments(
        maxSmallSegments);
    }

    @Override
    public int getMaxSmallSegments() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean()
          .getMaxSmallSegments();

      return Pair.this._zoieOne.getAdminMBean().getMaxSmallSegments();
    }

    @Override
    public long getDiskIndexSizeBytes() {
      long size = 0;
      if (Pair.this._zoieTwo != null) size = Pair.this._zoieTwo.getAdminMBean()
          .getDiskIndexSizeBytes();
      if (Pair.this._zoieOne != null) size += Pair.this._zoieTwo.getAdminMBean()
          .getDiskIndexSizeBytes();

      return size;
    }

    @Override
    public long getDiskFreeSpaceBytes() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean()
          .getDiskFreeSpaceBytes();

      return Pair.this._zoieOne.getAdminMBean().getDiskFreeSpaceBytes();
    }

    @Override
    public boolean isUseCompoundFile() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean().isUseCompoundFile();

      return Pair.this._zoieOne.getAdminMBean().isUseCompoundFile();
    }

    @Override
    public int getDiskIndexSegmentCount() throws IOException {
      int count = 0;
      if (Pair.this._zoieTwo != null) count = Pair.this._zoieTwo.getAdminMBean()
          .getDiskIndexSegmentCount();
      if (Pair.this._zoieOne != null) count += Pair.this._zoieTwo.getAdminMBean()
          .getDiskIndexSegmentCount();

      return count;
    }

    @Override
    public int getRAMASegmentCount() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean()
          .getRAMASegmentCount();

      return 0;
    }

    @Override
    public int getRAMBSegmentCount() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean()
          .getRAMBSegmentCount();

      return 0;
    }

    @Override
    public long getSLA() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean().getSLA();

      return Pair.this._zoieOne.getAdminMBean().getSLA();
    }

    @Override
    public void setSLA(long sla) {
      if (Pair.this._zoieTwo != null) Pair.this._zoieTwo.getAdminMBean().setSLA(sla);
      if (Pair.this._zoieOne != null) Pair.this._zoieOne.getAdminMBean().setSLA(sla);
    }

    @Override
    public long getHealth() {
      return ZoieHealth.getHealth();
    }

    @Override
    public void resetHealth() {
      ZoieHealth.setOK();
    }

    @Override
    public int getCurrentMemBatchSize() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean()
          .getCurrentMemBatchSize();

      return 0;
    }

    @Override
    public int getCurrentDiskBatchSize() {
      if (Pair.this._zoieTwo != null) return Pair.this._zoieTwo.getAdminMBean()
          .getCurrentDiskBatchSize();

      return Pair.this._zoieOne.getAdminMBean().getCurrentDiskBatchSize();
    }
  }

  @Override
  public void syncWithVersion(long timeInMillis, String version) throws ZoieException {
    if (_zoieTwo != null) {
      _zoieTwo.syncWithVersion(timeInMillis, version);
    }
  }

  @Override
  public void flushEvents(long timeout) throws ZoieException {
    if (_zoieTwo != null) {
      _zoieTwo.flushEvents(timeout);
    }
  }

  @Override
  public void consume(Collection<DataEvent<D>> data) throws ZoieException {
    if (_zoieTwo != null) {
      _zoieTwo.consume(data);
    }
  }

  @Override
  public String getVersion() {
    String v1 = null, v2 = null;
    Zoie<R, D> zoieOne = _zoieOne;
    if (zoieOne != null) {
      v1 = zoieOne.getVersion();
    }

    if (_zoieTwo != null) {
      v2 = _zoieTwo.getVersion();
    }

    return _zoieConfig.getVersionComparator().compare(v2, v1) > 0 ? v2 : v1;
  }

  @Override
  public String getCurrentReaderVersion() {
    String v1 = null, v2 = null;
    Zoie<R, D> zoieOne = _zoieOne;
    if (zoieOne != null) {
      v1 = zoieOne.getCurrentReaderVersion();
    }

    if (_zoieTwo != null) {
      v2 = _zoieTwo.getCurrentReaderVersion();
    }

    return _zoieConfig.getVersionComparator().compare(v2, v1) > 0 ? v2 : v1;
  }

  @Override
  public Comparator<String> getVersionComparator() {
    return _zoieConfig.getVersionComparator();
  }

  @Override
  public List<ZoieMultiReader<R>> getIndexReaders() throws IOException {
    List<ZoieMultiReader<R>> readers = new ArrayList<ZoieMultiReader<R>>();

    if (_zoieTwo != null) {
      readers.addAll(_zoieTwo.getIndexReaders());
    }

    Zoie<R, D> zoieOne = _zoieOne;
    if (zoieOne != null) {
      List<ZoieMultiReader<R>> zoieOneReaders = zoieOne.getIndexReaders();
      for (ZoieMultiReader<R> r : zoieOneReaders) {
        synchronized (_activeReaders) {
          ZoieRef zoieRef = _activeReaders.get(r);
          if (zoieRef != null) ++zoieRef.refCount;
          else {
            zoieRef = new ZoieRef(zoieOne);
            _activeReaders.put(r, zoieRef);
          }
        }
      }
      readers.addAll(zoieOneReaders);
    }

    return readers;
  }

  @Override
  public Analyzer getAnalyzer() {
    return _zoieConfig.getAnalyzer();
  }

  @SuppressWarnings({ "rawtypes", "unchecked" })
  @Override
  public void returnIndexReaders(List<ZoieMultiReader<R>> readers) {
    if (readers != null) {
      Map<Zoie<R, D>, List<ZoieMultiReader<R>>> destMap = new HashMap<Zoie<R, D>, List<ZoieMultiReader<R>>>();
      for (ZoieMultiReader<R> r : readers) {
        Zoie zoie = _zoieTwo;

        synchronized (_activeReaders) {
          ZoieRef zoieRef = _activeReaders.get(r);

          if (zoieRef != null) {
            zoie = zoieRef.zoie;
            --zoieRef.refCount;
            if (zoieRef.refCount <= 0) _activeReaders.remove(r);
          }
        }

        List<ZoieMultiReader<R>> readerList = destMap.get(zoie);
        if (readerList == null) {
          readerList = new ArrayList<ZoieMultiReader<R>>();
          destMap.put(zoie, readerList);
        }
        readerList.add(r);
      }

      for (Map.Entry<Zoie<R, D>, List<ZoieMultiReader<R>>> entry : destMap.entrySet()) {
        entry.getKey().returnIndexReaders(entry.getValue());
      }
    }
  }

  private static class ZoieRef {
    public Zoie<?, ?> zoie;
    public int refCount;

    public ZoieRef(Zoie<?, ?> zoie) {
      this.zoie = zoie;
    }
  }
}
TOP

Related Classes of proj.zoie.pair.impl.Pair$PairAdminMBean

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.