Package com.subgraph.orchid.directory.downloader

Source Code of com.subgraph.orchid.directory.downloader.DescriptorProcessor

package com.subgraph.orchid.directory.downloader;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import com.subgraph.orchid.ConsensusDocument;
import com.subgraph.orchid.Directory;
import com.subgraph.orchid.Router;
import com.subgraph.orchid.TorConfig;
import com.subgraph.orchid.TorConfig.AutoBoolValue;
import com.subgraph.orchid.data.HexDigest;

public class DescriptorProcessor {
  private final static int MAX_DL_PER_REQUEST = 96;
  private final static int MAX_DL_TO_DELAY = 16;
  private final static int MIN_DL_REQUESTS = 3;
  private final static int MAX_CLIENT_INTERVAL_WITHOUT_REQUEST = 10 * 60 * 1000;

  private final TorConfig config;
  private final Directory directory;
 
  private Date lastDescriptorDownload;
 
 
  DescriptorProcessor(TorConfig config, Directory directory) {
    this.config = config;
    this.directory = directory;
  }

  private boolean canDownloadDescriptors(int downloadableCount) {
    if(downloadableCount >= MAX_DL_TO_DELAY)
      return true;
    if(downloadableCount == 0)
      return false;
    if(lastDescriptorDownload == null)
      return true;
    final Date now = new Date();
    final long diff = now.getTime() - lastDescriptorDownload.getTime();
    return diff > MAX_CLIENT_INTERVAL_WITHOUT_REQUEST;
  }

  /*
   * dir-spec.txt section 5.3
   */
  private List< List<HexDigest> > partitionDescriptors(List<Router> descriptors) {
    final int size = descriptors.size();
    final List< List<HexDigest> > partitions = new ArrayList< List<HexDigest> >();
    if(size <= 10) {
      partitions.add(createPartitionList(descriptors, 0, size));
      return partitions;
    } else if(size <= (MIN_DL_REQUESTS * MAX_DL_PER_REQUEST)) {
      final int chunk = size / MIN_DL_REQUESTS;
      int over = size % MIN_DL_REQUESTS;
      int off = 0;
      for(int i = 0; i < MIN_DL_REQUESTS; i++) {
        int sz = chunk;
        if(over != 0) {
          sz++;
          over--;
        }
        partitions.add(createPartitionList(descriptors, off, sz));
        off += sz;
      }
      return partitions;
     
    } else {
      int off = 0;
      while(off < descriptors.size()) {
        partitions.add(createPartitionList(descriptors, off, MAX_DL_PER_REQUEST));
        off += MAX_DL_PER_REQUEST;
      }
      return partitions; 
    }
  }

  private List<HexDigest> createPartitionList(List<Router> descriptors, int offset, int size) {
    final List<HexDigest> newList = new ArrayList<HexDigest>();
    for(int i = offset; i < (offset + size) && i < descriptors.size(); i++) {
      final HexDigest digest = getDescriptorDigestForRouter(descriptors.get(i));
      newList.add(digest);
    }
    return newList;
  }

  private HexDigest getDescriptorDigestForRouter(Router r) {
    if(useMicrodescriptors()) {
      return r.getMicrodescriptorDigest();
    } else {
      return r.getDescriptorDigest();
    }
  }
 
  private boolean useMicrodescriptors() {
    return config.getUseMicrodescriptors() != AutoBoolValue.FALSE;
  }

  List< List<HexDigest> > getDescriptorDigestsToDownload() {
    final ConsensusDocument consensus = directory.getCurrentConsensusDocument();
    if(consensus == null || !consensus.isLive()) {
      return Collections.emptyList();
    }
    final List<Router> downloadables = directory.getRoutersWithDownloadableDescriptors();
    if(!canDownloadDescriptors(downloadables.size())) {
      return Collections.emptyList();
    }
   
    lastDescriptorDownload = new Date();
    return partitionDescriptors(downloadables);
  }
}
TOP

Related Classes of com.subgraph.orchid.directory.downloader.DescriptorProcessor

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.