<commit_before>/*
 * $Id: V3Voter.java,v 1.63 2008-10-02 06:47:39 tlipkis Exp $
 */

/*

Copyright (c) 2000-2008 Board of Trustees of Leland Stanford Jr. University,
all rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
STANFORD UNIVERSITY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of Stanford University shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Stanford University.

*/

package org.lockss.poller.v3;

import java.io.*;
import java.net.MalformedURLException;
import java.security.*;
import java.util.*;

import org.apache.commons.collections.*;

import org.lockss.app.*;
import org.lockss.config.*;
import org.lockss.daemon.CachedUrlSetHasher;
import org.lockss.hasher.*;
import org.lockss.plugin.*;
import org.lockss.poller.*;
import org.lockss.poller.v3.V3Serializer.PollSerializerException;
import org.lockss.protocol.*;
import org.lockss.protocol.V3LcapMessage.PollNak;
import org.lockss.protocol.psm.*;
import org.lockss.repository.RepositoryNode;
import org.lockss.state.*;
import org.lockss.scheduler.*;
import org.lockss.scheduler.Schedule.*;
import org.lockss.util.*;

/**
 * <p>Represents a voter in a V3 poll.</p>
 *
 * <p>State is maintained in a V3VoterState object, which is periodically 
 * serialized to disk so that polls may be resumed in case the daemon exits
 * before the poll is over.</p>
 */
public class V3Voter extends BasePoll {
  
  public static final int STATUS_INITIALIZED = 0;
  public static final int STATUS_ACCEPTED_POLL = 1;
  public static final int STATUS_HASHING = 2;
  public static final int STATUS_VOTED = 3;
  public static final int STATUS_NO_TIME = 4;
  public static final int STATUS_COMPLETE = 5;
  public static final int STATUS_EXPIRED = 6;
  public static final int STATUS_ERROR = 7;
  public static final int STATUS_DECLINED_POLL = 8;
  public static final int STATUS_VOTE_ACCEPTED = 9;
  
  public static final String[] STATUS_STRINGS = 
  {
   "Initialized", "Accepted Poll", "Hashing", "Voted",
   "No Time Available", "Complete", "Expired w/o Voting", "Error",
   "Declined Poll", "Vote Accepted"
  };

  private static final String PREFIX = Configuration.PREFIX + "poll.v3.";

  /** The minimum number of peers to select for a nomination message.
   * If there are fewer than this number of peers available to nominate,
   * an empty nomination message will be sent. */
  public static final String PARAM_MIN_NOMINATION_SIZE =
    PREFIX + "minNominationSize";
  public static final int DEFAULT_MIN_NOMINATION_SIZE = 1;

  /** The minimum number of peers to select for a nomination message. */
  public static final String PARAM_MAX_NOMINATION_SIZE = 
    PREFIX + "maxNominationSize";
  public static final int DEFAULT_MAX_NOMINATION_SIZE = 5;
  
  /** The maximum allowable number of simultaneous V3 Voters */
  public static final String PARAM_MAX_SIMULTANEOUS_V3_VOTERS =
    PREFIX + "maxSimultaneousV3Voters";
  public static final int DEFAULT_MAX_SIMULTANEOUS_V3_VOTERS = 60;
  
  /**
   * If false, do not serve any repairs via V3.
   */
  public static final String PARAM_ALLOW_V3_REPAIRS =
    PREFIX + "allowV3Repairs";
  public static final boolean DEFAULT_ALLOW_V3_REPAIRS = true;
  
  /**
   * If true, use per-URL agreement to determine whether it's OK to serve
   * a repair.  If false, rely on partial agreement level for serving
   * repairs.
   */
  public static final String PARAM_ENABLE_PER_URL_AGREEMENT =
    PREFIX + "enablePerUrlAgreement";
  public static final boolean DEFAULT_ENABLE_PER_URL_AGREEMENT = false;
  
  /**
   * The minimum percent agreement required before we're willing to serve
   * repairs, if using per-AU agreement.
   */
  // CR: apply to bytes, not URLs
  public static final String PARAM_MIN_PERCENT_AGREEMENT_FOR_REPAIRS =
    PREFIX + "minPercentAgreementForRepairs";
  public static final double DEFAULT_MIN_PERCENT_AGREEMENT_FOR_REPAIRS = 0.5f; 

  /**
   * If true, previous agreement will be required to serve repairs even for
   * open access AUs
   */
  public static final String PARAM_OPEN_ACCESS_REPAIR_NEEDS_AGREEMENT =
    PREFIX + "openAccessRepairNeedsAgreement";
  public static final boolean
    DEFAULT_OPEN_ACCESS_REPAIR_NEEDS_AGREEMENT = false;

  /** 
   * Allowance for vote message send time: hash time multiplier
   */
  public static final String PARAM_VOTE_SEND_HASH_MULTIPLIER =
    PREFIX + "voteMsgHashMultiplier";
  public static final double DEFAULT_VOTE_SEND_HASH_MULTIPLIER = 0.01;

  /** 
   * Allowance for vote message send time: padding
   */
  public static final String PARAM_VOTE_SEND_PADDING =
    PREFIX + "voteMsgPadding";
  public static final long DEFAULT_VOTE_SEND_PADDING = 15 * Constants.SECOND;

  /** 
   * Extra time added to the poll deadline (as sent by the poller) to 
   * wait for a receipt message.
   */
  public static final String PARAM_RECEIPT_PADDING = PREFIX + "receiptPadding";
  public static final long DEFAULT_RECEIPT_PADDING = 10 * Constants.MINUTE;

  /** 
   * Guess as to how long after we accept we'll get a vote request.
   * S.b. used to send vote request deadline to poller
   */
  public static final String PARAM_VOTE_REQUEST_DELAY =
    PREFIX + "voteRequestDelay";
  public static final long DEFAULT_VOTE_REQUEST_DELAY =
    30 * Constants.SECOND;

  /**
   * If true, previous agreement will be required to serve repairs even for
   * open access AUs
   */
  public static final String PARAM_RECALC_EXCESSIVE_HASH_ESTIMATE =
    PREFIX + "recalcExcessiveHashEstimate";
  public static final boolean DEFAULT_RECALC_EXCESSIVE_HASH_ESTIMATE = true;

  /** 
   * Factor of vote duration used as guess for duration of hash to recalc
   * hash estimate.
   */
  public static final String
    PARAM_RECALC_HASH_ESTIMATE_VOTE_DURATION_MULTIPLIER
    = PREFIX + "recalcHashEstimateVoteDurationMultiplier";
  /** Just used to document default */
  public static final String
    DEFAULT_RECALC_HASH_ESTIMATE_VOTE_DURATION_MULTIPLIER
    = "Twice reciprocal of " + V3Poller.PARAM_VOTE_DURATION_MULTIPLIER;

  /** Curve expressing decreasing weight of nominating peer who has
   * last voted in one of our polls X time ago.
   * @see org.lockss.util.CompoundLinearSlope */
  public static final String PARAM_NOMINATION_WEIGHT_AGE_CURVE =
    PREFIX + "nominationWeightAgeCurve";
  public static final String DEFAULT_NOMINATION_WEIGHT_AGE_CURVE =
    "[10d,1.0],[30d,0.1],[40d,0.01]";


  private PsmInterp stateMachine;
  private VoterUserData voterUserData;
  // CR: use global random
  private LockssRandom theRandom = new LockssRandom();
  private LockssDaemon theDaemon;
  private V3VoterSerializer pollSerializer;
  private PollManager pollManager;
  private IdentityManager idManager;
  private boolean continuedPoll = false;<commit_msg>Javadoc.<commit_after>/*
 * $Id: V3Voter.java,v 1.64 2008-10-02 07:42:17 tlipkis Exp $
 */

/*

Copyright (c) 2000-2008 Board of Trustees of Leland Stanford Jr. University,
all rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
STANFORD UNIVERSITY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of Stanford University shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Stanford University.

*/

package org.lockss.poller.v3;

import java.io.*;
import java.net.MalformedURLException;
import java.security.*;
import java.util.*;

import org.apache.commons.collections.*;

import org.lockss.app.*;
import org.lockss.config.*;
import org.lockss.daemon.CachedUrlSetHasher;
import org.lockss.hasher.*;
import org.lockss.plugin.*;
import org.lockss.poller.*;
import org.lockss.poller.v3.V3Serializer.PollSerializerException;
import org.lockss.protocol.*;
import org.lockss.protocol.V3LcapMessage.PollNak;
import org.lockss.protocol.psm.*;
import org.lockss.repository.RepositoryNode;
import org.lockss.state.*;
import org.lockss.scheduler.*;
import org.lockss.scheduler.Schedule.*;
import org.lockss.util.*;

/**
 * <p>Represents a voter in a V3 poll.</p>
 *
 * <p>State is maintained in a V3VoterState object, which is periodically 
 * serialized to disk so that polls may be resumed in case the daemon exits
 * before the poll is over.</p>
 */
public class V3Voter extends BasePoll {
  
  public static final int STATUS_INITIALIZED = 0;
  public static final int STATUS_ACCEPTED_POLL = 1;
  public static final int STATUS_HASHING = 2;
  public static final int STATUS_VOTED = 3;
  public static final int STATUS_NO_TIME = 4;
  public static final int STATUS_COMPLETE = 5;
  public static final int STATUS_EXPIRED = 6;
  public static final int STATUS_ERROR = 7;
  public static final int STATUS_DECLINED_POLL = 8;
  public static final int STATUS_VOTE_ACCEPTED = 9;
  
  public static final String[] STATUS_STRINGS = 
  {
   "Initialized", "Accepted Poll", "Hashing", "Voted",
   "No Time Available", "Complete", "Expired w/o Voting", "Error",
   "Declined Poll", "Vote Accepted"
  };

  private static final String PREFIX = Configuration.PREFIX + "poll.v3.";

  /** The minimum number of peers to select for a nomination message.
   * If there are fewer than this number of peers available to nominate,
   * an empty nomination message will be sent. */
  public static final String PARAM_MIN_NOMINATION_SIZE =
    PREFIX + "minNominationSize";
  public static final int DEFAULT_MIN_NOMINATION_SIZE = 1;

  /** The minimum number of peers to select for a nomination message. */
  public static final String PARAM_MAX_NOMINATION_SIZE = 
    PREFIX + "maxNominationSize";
  public static final int DEFAULT_MAX_NOMINATION_SIZE = 5;
  
  /** The maximum allowable number of simultaneous V3 Voters */
  public static final String PARAM_MAX_SIMULTANEOUS_V3_VOTERS =
    PREFIX + "maxSimultaneousV3Voters";
  public static final int DEFAULT_MAX_SIMULTANEOUS_V3_VOTERS = 60;
  
  /**
   * If false, do not serve any repairs via V3.
   */
  public static final String PARAM_ALLOW_V3_REPAIRS =
    PREFIX + "allowV3Repairs";
  public static final boolean DEFAULT_ALLOW_V3_REPAIRS = true;
  
  /**
   * If true, use per-URL agreement to determine whether it's OK to serve
   * a repair.  If false, rely on partial agreement level for serving
   * repairs.
   */
  public static final String PARAM_ENABLE_PER_URL_AGREEMENT =
    PREFIX + "enablePerUrlAgreement";
  public static final boolean DEFAULT_ENABLE_PER_URL_AGREEMENT = false;
  
  /**
   * The minimum percent agreement required before we're willing to serve
   * repairs, if using per-AU agreement.
   */
  // CR: apply to bytes, not URLs
  public static final String PARAM_MIN_PERCENT_AGREEMENT_FOR_REPAIRS =
    PREFIX + "minPercentAgreementForRepairs";
  public static final double DEFAULT_MIN_PERCENT_AGREEMENT_FOR_REPAIRS = 0.5f; 

  /**
   * If true, previous agreement will be required to serve repairs even for
   * open access AUs
   */
  public static final String PARAM_OPEN_ACCESS_REPAIR_NEEDS_AGREEMENT =
    PREFIX + "openAccessRepairNeedsAgreement";
  public static final boolean
    DEFAULT_OPEN_ACCESS_REPAIR_NEEDS_AGREEMENT = false;

  /** 
   * Allowance for vote message send time: hash time multiplier
   */
  public static final String PARAM_VOTE_SEND_HASH_MULTIPLIER =
    PREFIX + "voteMsgHashMultiplier";
  public static final double DEFAULT_VOTE_SEND_HASH_MULTIPLIER = 0.01;

  /** 
   * Allowance for vote message send time: padding
   */
  public static final String PARAM_VOTE_SEND_PADDING =
    PREFIX + "voteMsgPadding";
  public static final long DEFAULT_VOTE_SEND_PADDING = 15 * Constants.SECOND;

  /** 
   * Extra time added to the poll deadline (as sent by the poller) to 
   * wait for a receipt message.
   */
  public static final String PARAM_RECEIPT_PADDING = PREFIX + "receiptPadding";
  public static final long DEFAULT_RECEIPT_PADDING = 10 * Constants.MINUTE;

  /** 
   * Guess as to how long after we accept we'll get a vote request.
   * S.b. used to send vote request deadline to poller
   */
  public static final String PARAM_VOTE_REQUEST_DELAY =
    PREFIX + "voteRequestDelay";
  public static final long DEFAULT_VOTE_REQUEST_DELAY =
    30 * Constants.SECOND;

  /**
   * If true, previous agreement will be required to serve repairs even for
   * open access AUs
   */
  public static final String PARAM_RECALC_EXCESSIVE_HASH_ESTIMATE =
    PREFIX + "recalcExcessiveHashEstimate";
  public static final boolean DEFAULT_RECALC_EXCESSIVE_HASH_ESTIMATE = true;

  /** 
   * Factor of vote duration used as guess for duration of hash to recalc
   * hash estimate.
   */
  public static final String
    PARAM_RECALC_HASH_ESTIMATE_VOTE_DURATION_MULTIPLIER
    = PREFIX + "recalcHashEstimateVoteDurationMultiplier";
  /** Just used to document default */
  public static final String
    DEFAULT_RECALC_HASH_ESTIMATE_VOTE_DURATION_MULTIPLIER
    = "Twice reciprocal of " + V3Poller.PARAM_VOTE_DURATION_MULTIPLIER;

  /** Curve expressing decreasing weight of nominating peer who has last
   * voted in one of our polls X time ago.  X coord is time (ms) since last
   * vote, Y is float nomination weight.
   * @see org.lockss.util.CompoundLinearSlope */
  public static final String PARAM_NOMINATION_WEIGHT_AGE_CURVE =
    PREFIX + "nominationWeightAgeCurve";
  public static final String DEFAULT_NOMINATION_WEIGHT_AGE_CURVE =
    "[10d,1.0],[30d,0.1],[40d,0.01]";


  private PsmInterp stateMachine;
  private VoterUserData voterUserData;
  // CR: use global random
  private LockssRandom theRandom = new LockssRandom();
  private LockssDaemon theDaemon;
  private V3VoterSerializer pollSerializer;
  private PollManager pollManager;
  private IdentityManager idManager;
  private boolean continuedPoll = false;
{'fraction_non_alphanumeric': 0.06788979096081314, 'fraction_numerical': 0.010483922521255514, 'mean_word_length': 4.181848294137131, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5434686', 'n_tokens_mistral': 4988, 'n_tokens_neox': 4676, 'n_words': 1690}