Ejemplo n.º 1
0
        public BigFilePackOperationStatus PackBigFile(BigFilePackOptions options)
        {
            if (options.Threads > MAX_PACK_THREADS)
            {
                log.Error(string.Format("Can't have more threads than the max! ({0} > {1})", options.Threads, MAX_PACK_THREADS));
                log.Error("    Threads will be clamped to the max!");
                options.Threads = MAX_PACK_THREADS;
            }
            else if (options.Threads <= 0)
            {
                log.Error("What in the name of all that is good and holy are you trying to do?");
                log.Error("    (BigFilePackOptions threads <= 0)");
                return(null);
            }

            log.Info("Packing a big file to directory: " + options.Directory.FullName);

            //MAKE SURE DECOMPRESS FLAG IS SET
            // otherwise we run the risk of not decompressing files when we need to
            options.Flags |= BigFileFlags.Decompress;

            options.Log(log);

            if (!options.Directory.Exists)
            {
                log.Info("Creating directory...");
                Directory.CreateDirectory(options.Directory.FullName);
            }

            VerifyAndResetPackInfos(options.Threads);

            if ((options.Flags & BigFileFlags.UseThreading) != 0)
            {
                return(internal_ThreadedPack(options));
            }
            else
            {
                log.Error("Single threaded pack not supported!");

                //packInfos[0].Options = options;
                //packInfos[0].startIndex = 0;
                //packInfos[0].count = bigFile.FileMap.FilesList.Length;
                //packInfos[0].bigFile = bigFile;
                //packInfos[0].OnCompleted = internal_OnPackFinished;

                //internal_GenBigFileChunk(packInfos[0]);

                //log.Info("Finished pack!");

                return(null);
            }
        }
Ejemplo n.º 2
0
        private BigFilePackOperationStatus internal_ThreadedPack(BigFilePackOptions options)
        {
            //set up threads
            int dividedCount     = bigFile.FileMap.FilesList.Length / options.Threads;
            int dividedRemainder = bigFile.FileMap.FilesList.Length % options.Threads;

            log.Info("Divided files into " + options.Threads + " pools of " + dividedCount + " with " + dividedRemainder + " left over (to be tacked onto the last!)");

            BigFileFile[] files = new BigFileFile[bigFile.FileMap.FilesList.Length];
            Array.Copy(bigFile.FileMap.FilesList, files, files.Length);
            Array.Sort(files,
                       (fileA, fileB) =>
            {
                return(fileA.FileInfo.Offset.CompareTo(fileB.FileInfo.Offset));
            });

            List <BigFilePackInfo> infos = new List <BigFilePackInfo>();

            for (int i = 0; i < options.Threads; i++)
            {
                packInfos[i].Options    = options;
                packInfos[i].startIndex = i * dividedCount;
                packInfos[i].count      = dividedCount;
                packInfos[i].bigFile    = bigFile;
                packInfos[i].filesList  = files;
            }
            packInfos[options.Threads - 1].count      += dividedRemainder;
            packInfos[options.Threads - 1].OnCompleted = internal_OnPackFinished; //the last thread gets the job of stitching together the chunks

            for (int i = 0; i < options.Threads; i++)
            {
                ThreadPool.QueueUserWorkItem(internal_GenBigFileChunk, packInfos[i]);
                infos.Add(packInfos[i]);
            }

            return(new BigFilePackOperationStatus(infos));
        }