Package me.mabra.hellonzb.nntpclient

Source Code of me.mabra.hellonzb.nntpclient.BackupFileDownloader$DlSegmentQueue

/*
* HelloNzb -- The Binary Usenet Tool
* Copyright (C) 2010-2013 Matthias F. Brandstetter
* https://sourceforge.net/projects/hellonzb/
*
* 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 3 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/>.
*/

package me.mabra.hellonzb.nntpclient;

import me.mabra.hellonzb.HelloNzb;
import me.mabra.hellonzb.parser.DownloadFile;
import me.mabra.hellonzb.util.MyLogger;
import me.mabra.hellonzb.nntpclient.nioengine.RspHandler;
import me.mabra.hellonzb.nntpclient.nioengine.NettyNioClient;
import me.mabra.hellonzb.parser.DownloadFileSegment;

import java.awt.*;
import java.util.ArrayList;


/**
* Similar to the main NntpFileDownloader class.
* But used for connections to the backup server (if set).
*
* @author Matthias F. Brandstetter
*/
public class BackupFileDownloader implements Runnable
{
  final private HelloNzb mainApp;
  final private NettyNioClient nioClient;
  final private MyLogger logger;

  private DlSegmentQueue segQueue;
  private ArrayList<RspHandler> activeRspHandlers;
  private ArrayList<RspHandler> finishedRspHandlers;

  private boolean pause;
  private boolean shutdown;


  /**
   * Class constructor.
   */
  public BackupFileDownloader(HelloNzb main, NettyNioClient client)
  {
    mainApp = main;
    nioClient = client;
    logger = mainApp.getLogger();

    pause = false;
    shutdown = false;

    segQueue = new DlSegmentQueue();
    activeRspHandlers = new ArrayList<>();
    finishedRspHandlers = new ArrayList<>();
  }

  /**
   * This method starts the thread and makes this backup file downloader available.
   */
  public void run()
  {
    int runningThreads = 0;
    final int maxThreads = Integer.parseInt(mainApp.getPrefValue("ServerSettingsBackupThreadCount"));

    while(!shutdown)
    {
      while(segQueue.hasSegments() && runningThreads < maxThreads && !pause && nioClient.hasFreeSlot())
      {
        // get next segment in queue
        DownloadFileSegment nextSeg = segQueue.nextSegment();
        if(nextSeg == null)
          break;
        String filename = nextSeg.getDlFile().getFilename();
        logger.msg("Downloading from backup server next segment of file: " + filename, MyLogger.SEV_DEBUG);

        // create new response handler
        RspHandler newHandler = new RspHandler(nextSeg, true);
        synchronized(activeRspHandlers)
        {
          activeRspHandlers.add(newHandler);
        }

        // start data download and increase thread counter
        nioClient.fetchArticleData(nextSeg.getGroups().firstElement(), nextSeg.getArticleId(), newHandler);
        runningThreads++;
      }

      // check if the next element of the result set is already finished
      int actRspHdlsSize;
      synchronized(activeRspHandlers)
      {
        actRspHdlsSize = activeRspHandlers.size();
      }

      ArrayList<RspHandler> toRemoveVector = new ArrayList<>();
      for(int i = 0; i < actRspHdlsSize; i++)
      {
        RspHandler handler;
        synchronized(activeRspHandlers)
        {
          handler = activeRspHandlers.get(i);
        }

        // all data downloaded?
        if(handler.isFinished())
        {
          synchronized(finishedRspHandlers)
          {
            finishedRspHandlers.add(handler);
          }

          toRemoveVector.add(handler);
          runningThreads--;
        }
      }

      // remove all finished handlers from active queue
      synchronized(activeRspHandlers)
      {
        activeRspHandlers.removeAll(toRemoveVector);
      }
      toRemoveVector.clear();

      try
      {
        Thread.sleep(10);
      }
      catch(InterruptedException ex)
      {
        shutdown = true;
      }
    }  // end of main loop

    logger.msg("Backup FileDownloader loop ended.", MyLogger.SEV_DEBUG);
  }

  /**
   * Check whether the given filename is currently being downloaded.
   */
  public boolean isActivelyDownloaded(String filename)
  {
    synchronized(activeRspHandlers)
    {
      for(RspHandler handler : activeRspHandlers)
      {
        String handlerFile = handler.dlFileSeg().getDlFile().getFilename();
        if(filename.equals(handlerFile))
          return true;
      }
    }

    synchronized(finishedRspHandlers)
    {
      for(RspHandler handler : finishedRspHandlers)
      {
        String handlerFile = handler.dlFileSeg().getDlFile().getFilename();
        if(filename.equals(handlerFile))
          return true;
      }
    }

    return false;
  }

  /**
   * Add a new segment to download to this downloader's queue.
   */
  public void addSegment(DownloadFileSegment seg)
  {
    segQueue.addSegment(seg);
  }

  /**
   * Remove all those segements from the queue, that belong to the given file.
   */
  public void removeFileSegmentsFromQueue(String filename)
  {
    segQueue.removeSegments(filename);
  }

  /**
   * Get all finished response handlers.
   */
  public ArrayList<RspHandler> getFinishedHandlers()
  {
    synchronized(finishedRspHandlers)
    {
      ArrayList<RspHandler> result = new ArrayList<>(finishedRspHandlers);
      finishedRspHandlers.clear();
      return result;
    }
  }

  /**
   * Whether or not one or more response handler(s) is/are ready.
   */
  public boolean hasFinishedHandlers()
  {
    synchronized(finishedRspHandlers)
    {
      return finishedRspHandlers.size() > 0;
    }
  }

  /**
   * Called from main app when this thread should pause working.
   */
  public void setPaused(boolean p)
  {
    pause = p;
  }

  /**
   * Shutdown this downloader, which stops the parent thread.
   */
  public void shutdown()
  {
    shutdown = true;
  }


  /******************************************************************************************/
  public class DlSegmentQueue
  {
    private ArrayList<DownloadFileSegment> queue;


    public DlSegmentQueue()
    {
      queue = new ArrayList<>();
    }

    synchronized void addSegment(DownloadFileSegment segment)
    {
      assert segment != null;
      queue.add(segment);
    }

    synchronized DownloadFileSegment nextSegment()
    {
      if(hasSegments())
        return queue.remove(0);
      else
        return null;
    }

    synchronized void removeSegments(String filename)
    {
      ArrayList<DownloadFileSegment> toRemove = new ArrayList<>();
      for(DownloadFileSegment seg : queue)
      {
        DownloadFile dlFile = seg.getDlFile();
        if(dlFile.getFilename().equals(filename))
          toRemove.add(seg);
      }

      queue.removeAll(toRemove);
    }

    synchronized boolean hasSegments()
    {
      return queue.size() > 0;
    }
  }
}
TOP

Related Classes of me.mabra.hellonzb.nntpclient.BackupFileDownloader$DlSegmentQueue

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.