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); } }
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)); }