private void Execute() { try { lock (this) { // Wait 2 seconds, Monitor.Wait(2000); // Any new block containers added, we need to process, List <BlockContainer> newItems = new List <BlockContainer>(); while (true) { lock (service.compressionAddList) { newItems.AddRange(service.compressionAddList); service.compressionAddList.Clear(); } // Sort the container list, newItems.Sort(); newItems.Reverse(); for (int i = newItems.Count - 1; i >= 0; i--) { BlockContainer container = newItems[i]; // If it's already compressed, remove it from the list if (container.IsCompressed) { newItems.RemoveAt(i); } // Don't compress if written to less than 3 minutes ago, // and we confirm it can be compressed, else if (service.IsKnownStaticBlock(container)) { FileBlockStore mblockStore = (FileBlockStore)container.Store; string sourcef = mblockStore.FileName; string destf = Path.Combine(Path.GetDirectoryName(sourcef), Path.GetFileName(sourcef) + ".tempc"); try { File.Delete(destf); service.Logger.Info(String.Format("Compressing block: {0}", container.Id)); service.Logger.Info(String.Format("Current block size = {0}", sourcef.Length)); // Compress the file, CompressedBlockStore.Compress(sourcef, destf); // Rename the file, string compressedf = Path.Combine(Path.GetDirectoryName(sourcef), Path.GetFileName(sourcef) + ".mcd"); File.Move(destf, compressedf); // Switch the block container, container.ChangeStore(new CompressedBlockStore(container.Id, compressedf)); service.Logger.Info(String.Format("Compression of block {0} finished.", container.Id)); service.Logger.Info(String.Format("Compressed block size = {0}", compressedf.Length)); // Wait a little bit and delete the original file, if (finished) { hasFinished = true; Monitor.PulseAll(this); return; } Monitor.Wait(this, 1000); // Delete the file after 5 minutes, new Timer(FileDelete, sourcef, 5 * 60 * 1000, Timeout.Infinite); // Remove it from the new_items list newItems.RemoveAt(i); } catch (IOException e) { service.Logger.Error("IO Error in compression thread", e); } } if (finished) { hasFinished = true; Monitor.PulseAll(this); return; } Monitor.Wait(this, 200); } if (finished) { hasFinished = true; Monitor.PulseAll(this); return; } Monitor.Wait(this, 3000); } } } catch (ThreadInterruptedException) { // ThreadInterruptedException causes the thread to end, } }