Package com.ettrema.zsync

Source Code of com.ettrema.zsync.FileUpdater

/* FileMaker.java

FileMaker: File reading and making class
Copyright (C) 2011 Tomáš Hlavnička <hlavntom@fel.cvut.cz>

This file is a part of Jazsync.

Jazsync 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.

Jazsync 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 Jazsync; if not, write to the

Free Software Foundation, Inc.,
59 Temple Place, Suite 330,
Boston, MA  02111-1307
USA
*/
package com.ettrema.zsync;

import com.bradmcevoy.http.Range;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* @author brad, original work by Tomáš Hlavnička
*/
public class FileUpdater {

  private static final Logger log = LoggerFactory.getLogger(FileUpdater.class);
  /**
   * Maximum ranges to download in the range header
   */
  private int maxRanges = 100;

  /**
   * Method for completing file
   */
  public void update(File inputFile, MetaFileReader mfr, RangeLoader rangeLoader, MakeContext mc, File newFile) throws Exception {
    log.trace("fileMaker: input: " + inputFile.getAbsolutePath());
    try {
      double a = 10;
      int range = 0;
      int blockLength = 0;
      List<Range> rangeList = null;
      byte[] data = null;
      FileChannel wChannel = null;

      newFile.createNewFile();
      log.trace("Writing new file: " + newFile.getAbsolutePath());
      wChannel = new FileOutputStream(newFile, true).getChannel();

      ByteBuffer buffer = ByteBuffer.allocate(mfr.getBlocksize());
      log.trace("Reading from file: " + inputFile.getAbsolutePath());
      FileChannel rChannel = new FileInputStream(inputFile).getChannel();
      log.trace("number of map entries: " + mc.fileMap.length);
      for (int i = 0; i < mc.fileMap.length; i++) {
        mc.fileOffset = mc.fileMap[i];
        if (mc.fileOffset != -1) {
          log.trace("  read block from local file: " + mc.fileOffset);
          rChannel.read(buffer, mc.fileOffset);
          buffer.flip();
          wChannel.write(buffer);
          buffer.clear();
        } else {
          log.trace("   read block from remote file");
          if (!mc.rangeQueue) {
            rangeList = rangeLookUp(i, mfr.getBlocksize(), mc);
            range = rangeList.size();
            data = rangeLoader.get(rangeList);
            System.out.println("got data length: " + data.length);
          } else {
            log.trace("     already have queued ranges: " + rangeList.size());
          }
          blockLength = calcBlockLength(i, mfr.getBlocksize(), (int) mfr.getLength());
          int offset = (range - rangeList.size()) * mfr.getBlocksize();
          System.out.println("blockLength: " + blockLength + " data.length: " + data.length + "  offset: " + offset);
          buffer.put(data, offset, blockLength);
          buffer.flip();
          wChannel.write(buffer);
          buffer.clear();
          rangeList.remove(0);
          if (rangeList.isEmpty()) {
            mc.rangeQueue = false;
          }
        }
      }
      log.info("Completed file: " + newFile.getAbsolutePath());
      log.info("Checking checksums...");
      SHA1 sha = new SHA1(newFile);
      String actual = sha.SHA1sum();
      String expected = mfr.getSha1();

      if (actual.equals(expected)) {
        log.info("checksum matches OK");
//        System.out.println("used " + (mfr.getLength() - (mfr.getBlocksize() * missing)) + " " + "local, fetched " + (mfr.getBlocksize() * missing));
//        new File(mfr.getFilename()).renameTo(new File(mfr.getFilename() + ".zs-old"));
//        newFile.renameTo(new File(mfr.getFilename()));
//        allData += mfr.getLengthOfMetafile();
//        System.out.println("really downloaded " + allData);
//        double overhead = ((double) (allData - (mfr.getBlocksize() * missing)) / ((double) (mfr.getBlocksize() * missing))) * 100;
//        System.out.println("overhead: " + df.format(overhead) + "%");
      } else {
        log.error("Checksums don't match - expected: " + expected + "  actual: " + actual);
        throw new RuntimeException("Checksums don't match - expected: " + expected + "  actual: " + actual);
      }
    } catch (IOException ex) {
      throw new RuntimeException("Can't read or write, check your permissions.");
    }
  }

  /**
   * Instead of downloading single blocks, we can look into fieMap and collect
   * amount of missing blocks or end of map accurs. Single ranges are stored in
   * ArrayList
   * @param i Offset in fileMap where to start looking
   * @return ArrayList with ranges for requesting
   */
  private List<Range> rangeLookUp(int i, int blocksize, MakeContext mc) {
    List<Range> ranges = new ArrayList<Range>();
    for (; i < mc.fileMap.length; i++) {
      if (mc.fileMap[i] == -1) {
        ranges.add(new Range(i * blocksize,(i * blocksize) + blocksize));
      }
      if (ranges.size() >= maxRanges) {
        break;
      }
    }
    if (!ranges.isEmpty()) {
      mc.rangeQueue = true;
    }
    return ranges;
  }

  private int calcBlockLength(int i, int blockSize, int length) {
    if ((i+1) * blockSize < length) {
      return blockSize;
    } else {
      return calcBlockLength_b(i, blockSize, length);
    }
  }

  private int calcBlockLength_b(int i, int blockSize, int length) {
    return blockSize + (length - (i * blockSize + blockSize));
  }
}
TOP

Related Classes of com.ettrema.zsync.FileUpdater

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.