Package com.moesol.geoserver.sync.grouper

Source Code of com.moesol.geoserver.sync.grouper.Sha1LevelGrouper

/**
*
*  #%L
*  geoserver-sync-core
*  $Id:$
*  $HeadURL:$
*  %%
*  Copyright (C) 2013 Moebius Solutions Inc.
*  %%
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as
*  published by the Free Software Foundation, either version 2 of the
*  License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public
*  License along with this program.  If not, see
<http://www.gnu.org/licenses/gpl-2.0.html>.
*  #L%
*
*/

package com.moesol.geoserver.sync.grouper;


import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.moesol.geoserver.sync.core.IdAndValueSha1Comparator;
import com.moesol.geoserver.sync.core.IdAndValueSha1s;
import com.moesol.geoserver.sync.core.Sha1Value;
import com.moesol.geoserver.sync.core.VersionFeatures;

public abstract class Sha1LevelGrouper {
  private static final Logger LOGGER = Logger.getLogger(Sha1JsonLevelGrouper.class.getName());
  private final MessageDigest m_sha1;
  private final List<? extends IdAndValueSha1s> m_sortedFeatureSha1s;
  protected final VersionFeatures versionFeatures;
  private long m_maxInAnyGroup = 0;

  /**
   * Prepares grouper by sorting featureSha1s in place.
   * @param featureSha1s list of SHA-1 checksums for features.
   */
  public Sha1LevelGrouper(VersionFeatures vf, List<? extends IdAndValueSha1s> featureSha1s) {
    versionFeatures = vf;
    try {
      m_sha1 = MessageDigest.getInstance("SHA-1");
    } catch (NoSuchAlgorithmException e) {
      throw new IllegalStateException("Unable to load SHA-1 message digest", e);
    }
    Collections.sort(featureSha1s, new IdAndValueSha1Comparator(versionFeatures));
    m_sortedFeatureSha1s = featureSha1s;
  }
 
  public void groupForLevel(int level) {
    begin(level);
    m_maxInAnyGroup = 0;
    try {
      if (level == 0) {
        sha1All();
        return;
      }
      sha1Groups(level);
    } finally {
      end(m_maxInAnyGroup);
    }
  }

  private void sha1All() {
    for (IdAndValueSha1s sha1 : m_sortedFeatureSha1s) {
      hashOne(sha1.getValueSha1());
      m_maxInAnyGroup++;
    }
    doGroupCompleted(new GroupPosition(0), new Sha1Value(m_sha1.digest()), m_maxInAnyGroup);
  }

  /**
   * Walks all the feature sha1s and computes the groups of sha1s for {@code level}.
   * @param level
   */
  private void sha1Groups(int level) {
    GroupPosition prefix = new GroupPosition(level);
    long maxCurrentGroup = 0;
   
    // Hmm, this could be written in terms of NavigableSet operations...
    if (m_sortedFeatureSha1s.size() > 0) {
      IdAndValueSha1s zero = m_sortedFeatureSha1s.get(0);
      prefix.setFromSha1(versionFeatures.getBucketPrefixSha1(zero));
      hashOne(zero.getValueSha1());
      maxCurrentGroup++;
    }
    for (int i = 1; i < m_sortedFeatureSha1s.size(); i++) {
      IdAndValueSha1s sha1 = m_sortedFeatureSha1s.get(i);

      if (versionFeatures.getBucketPrefixSha1(sha1).isPrefixMatch(prefix)) {
        hashOne(sha1.getValueSha1());
        maxCurrentGroup++;
        continue;
      }
     
      if (i < m_sortedFeatureSha1s.size()) {
        doGroupCompleted(prefix, new Sha1Value(m_sha1.digest()), maxCurrentGroup);
        updateMaxInGroup(maxCurrentGroup);
        maxCurrentGroup = 0;
        hashOne(sha1.getValueSha1());
        maxCurrentGroup++;
        prefix.setFromSha1(versionFeatures.getBucketPrefixSha1(sha1));
      }
    }
    if (m_sortedFeatureSha1s.size() > 0) {
      doGroupCompleted(prefix, new Sha1Value(m_sha1.digest()), maxCurrentGroup);
      updateMaxInGroup(maxCurrentGroup);
      maxCurrentGroup = 0;
    }
  }

  protected void hashOne(Sha1Value sha1) {
    LOGGER.log(Level.FINER, "el({0})", sha1);
    m_sha1.update(sha1.get());
  }
 
  private void doGroupCompleted(GroupPosition position, Sha1Value sha1Value, long maxInGroup) {
    LOGGER.log(Level.FINER, "--group({0},{1},{2})", new Object[] {position, sha1Value, maxInGroup });
    groupCompleted(position, sha1Value);
  }

  private void updateMaxInGroup(long maxCurrentGroup) {
    if (m_maxInAnyGroup < maxCurrentGroup) {
      m_maxInAnyGroup = maxCurrentGroup;
    }
  }
 
  protected abstract void begin(int level);
  protected abstract void groupCompleted(GroupPosition position, Sha1Value sha1Value);
  protected abstract void end(long maxInAnyGroup);
}
TOP

Related Classes of com.moesol.geoserver.sync.grouper.Sha1LevelGrouper

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.