Skip to content

Commit

Permalink
Add option to set maximum thread count for compression (and uncompres…
Browse files Browse the repository at this point in the history
…sion)

Add option to lock HDD threads to 1 (minimises performance impact, reduces fragmentation, can improve speed due to reduction in seek times)
All background compression is now limited to one thread.
Update Version
  • Loading branch information
Iridium-IO committed Jan 24, 2025
1 parent 8ab872f commit f000abe
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 18 deletions.
17 changes: 15 additions & 2 deletions CompactGUI.Core/Compactor.vb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Imports System.Runtime.InteropServices
Imports System.Threading


Public Class Compactor : Implements IDisposable

Public Sub New(folder As String, cLevel As CompressionAlgorithm, excludedFilesTypes As String())
Expand Down Expand Up @@ -33,21 +34,33 @@ Public Class Compactor : Implements IDisposable



Public Async Function RunCompactAsync(Optional progressMonitor As IProgress(Of (percentageProgress As Integer, currentFile As String)) = Nothing) As Task(Of Boolean)
Public Async Function RunCompactAsync(Optional progressMonitor As IProgress(Of (percentageProgress As Integer, currentFile As String)) = Nothing, Optional MaxParallelism As Integer = 1) As Task(Of Boolean)
If _cancellationTokenSource.IsCancellationRequested Then Return False

Dim FilesList = Await BuildWorkingFilesList()
Dim totalFilesSize As Long = FilesList.Sum(Function(f) f.Item2)
_processedFilesBytes = 0

If MaxParallelism <= 0 Then MaxParallelism = Environment.ProcessorCount


Dim sw As New Stopwatch
sw.Start()

Dim paraOptions As New ParallelOptions With {.MaxDegreeOfParallelism = MaxParallelism}

Await Parallel.ForEachAsync(FilesList,
Await Parallel.ForEachAsync(FilesList, paraOptions,
Function(file, _ctx) As ValueTask
If _ctx.IsCancellationRequested Then Return ValueTask.FromCanceled(_ctx)
Return New ValueTask(PauseAndProcessFile(file.Item1, _cancellationTokenSource.Token, file.Item2, totalFilesSize, progressMonitor))
End Function).ConfigureAwait(False)


sw.Stop()

Debug.WriteLine($"Completed in {sw.Elapsed.TotalSeconds} s")


If _cancellationTokenSource.IsCancellationRequested Then Return False

Return True
Expand Down
18 changes: 16 additions & 2 deletions CompactGUI.Core/Uncompactor.vb
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,30 @@ Public Class Uncompactor
Private _cancellationTokenSource As New CancellationTokenSource


Public Async Function UncompactFiles(filesList As List(Of String), Optional progressMonitor As IProgress(Of (percentageProgress As Integer, currentFile As String)) = Nothing) As Task(Of Boolean)
Public Async Function UncompactFiles(filesList As List(Of String), Optional progressMonitor As IProgress(Of (percentageProgress As Integer, currentFile As String)) = Nothing, Optional MaxParallelism As Integer = 1) As Task(Of Boolean)

Dim totalFiles As Integer = filesList.Count

If MaxParallelism <= 0 Then MaxParallelism = Environment.ProcessorCount

Dim paraOptions As New ParallelOptions With {.MaxDegreeOfParallelism = MaxParallelism}


Dim sw As New Stopwatch
sw.Start()


_processedFileCount.Clear()
Await Parallel.ForEachAsync(filesList,
Await Parallel.ForEachAsync(filesList, paraOptions,
Function(file, _ctx) As ValueTask
If _ctx.IsCancellationRequested Then Return ValueTask.FromCanceled(_ctx)
Return New ValueTask(PauseAndProcessFile(file, _cancellationTokenSource.Token, totalFiles, progressMonitor))
End Function).ConfigureAwait(False)


sw.Stop()
Debug.WriteLine($"Completed in {sw.Elapsed.TotalSeconds} s")

Return True
End Function

Expand Down
1 change: 1 addition & 0 deletions CompactGUI/CompactGUI.vbproj
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="diskdetector-net" Version="0.3.2" />
<PackageReference Include="Fody" Version="6.8.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
9 changes: 9 additions & 0 deletions CompactGUI/Models/ActiveFolder.vb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Imports System.Collections.ObjectModel

Imports Microsoft.Toolkit.Mvvm.ComponentModel
Imports DiskDetector

Public Class ActiveFolder : Inherits ObservableObject

Expand All @@ -19,6 +20,14 @@ Public Class ActiveFolder : Inherits ObservableObject

Public Property IsFreshlyCompressed As Boolean = False

Public ReadOnly Property DiskType As DiskDetector.Models.HardwareType
Get
If FolderName Is Nothing Then Return Models.HardwareType.Unknown
Return DiskDetector.Detector.DetectDrive(FolderName.First, DiskDetector.Models.QueryType.RotationRate).HardwareType

End Get
End Property

Public ReadOnly Property CompressionRatio As Decimal
Get
If UncompressedBytes = 0 OrElse CompressedBytes = 0 OrElse CompressedBytes = 1010101010101010 Then Return 0
Expand Down
3 changes: 3 additions & 0 deletions CompactGUI/Models/Settings.vb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Public Class Settings : Inherits ObservableObject
Public Property ShowNotifications As Boolean = False
Public Property StartInSystemTray As Boolean = False

Public Property MaxCompressionThreads As Integer = 0
Public Property LockHDDsToOneThread As Boolean = True

Private _EnableBackgroundWatcher As Boolean = True
Public Property EnableBackgroundWatcher As Boolean
Get
Expand Down
2 changes: 1 addition & 1 deletion CompactGUI/Models/UpdateHandler.vb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Imports System.Text.Json
Public Class UpdateHandler

Public Shared Property CurrentVersion As New SemVersion(3, 5, 1)
Public Shared Property CurrentVersion As New SemVersion(3, 6, 0)
Public Shared Property NewVersion As SemVersion
Public Shared ReadOnly UpdateURL As String = "https://raw.githubusercontent.com/IridiumIO/CompactGUI/database/version.json"
Public Shared ReadOnly httpClient As New HttpClient()
Expand Down
5 changes: 3 additions & 2 deletions CompactGUI/ViewModels/MainViewModel.vb
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,13 @@ Public Class MainViewModel : Inherits ObservableObject
PauseResumeStatus = "Pause"
CancelStatus = "Cancel"


CProgress.Report((0, ""))

Dim exclist As String() = GetSkipList()

CoreCompactor = New Core.Compactor(ActiveFolder.FolderName, Core.WOFConvertCompressionLevel(ActiveFolder.SelectedCompressionMode), exclist)
Dim res = Await CoreCompactor.RunCompactAsync(CProgress)
Dim res = Await CoreCompactor.RunCompactAsync(CProgress, If(ActiveFolder.DiskType = DiskDetector.Models.HardwareType.Hdd AndAlso SettingsHandler.AppSettings.LockHDDsToOneThread, 1, SettingsHandler.AppSettings.MaxCompressionThreads))

ActiveFolder.IsFreshlyCompressed = False
If res Then ActiveFolder.IsFreshlyCompressed = True
Expand Down Expand Up @@ -236,7 +237,7 @@ Public Class MainViewModel : Inherits ObservableObject

Dim compressedFilesList = ActiveFolder.AnalysisResults.Where(Function(rs) rs.CompressedSize < rs.UncompressedSize).Select(Of String)(Function(f) f.FileName).ToList
CoreUncompactor = New Core.Uncompactor
Await CoreUncompactor.UncompactFiles(compressedFilesList, CProgress)
Await CoreUncompactor.UncompactFiles(compressedFilesList, CProgress, If(ActiveFolder.DiskType = DiskDetector.Models.HardwareType.Hdd AndAlso SettingsHandler.AppSettings.LockHDDsToOneThread, 1, SettingsHandler.AppSettings.MaxCompressionThreads))

ActiveFolder.IsFreshlyCompressed = False

Expand Down
49 changes: 38 additions & 11 deletions CompactGUI/Views/SettingsView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
<StackPanel Margin="0,40,0,0">
<Label Content="Filetype Management" FontWeight="SemiBold" />

<StackPanel Margin="10,10,0,5">
<Grid Margin="0,0,0,5">
<StackPanel Margin="10,5,0,5">
<Grid Margin="0,0,0,2">
<TextBlock Text="manage local skipped filetypes"
VerticalAlignment="Center"
FontSize="14" />
Expand Down Expand Up @@ -77,26 +77,49 @@
<Separator Margin="0,5,0,5" />
<Label Content="System Integration" FontWeight="SemiBold" />
<StackPanel Margin="10,5,0,7">
<CheckBox x:Name="uiIsContextEnabled"
<CheckBox x:Name="uiIsContextEnabled" Margin="0,-3"
Content="add to right-click context menu"
IsChecked="{Binding AppSettings.IsContextIntegrated, Mode=TwoWay}" />
<CheckBox x:Name="uiIsStartMenuEnabled"
<CheckBox x:Name="uiIsStartMenuEnabled" Margin="0,-3"
Content="add to start menu"
IsChecked="{Binding AppSettings.IsStartMenuEnabled, Mode=TwoWay}"
/>
<CheckBox x:Name="uiShowNotifications"
<CheckBox x:Name="uiShowNotifications" Margin="0,-3"
Content="show notification on completion"
IsChecked="{Binding AppSettings.ShowNotifications, Mode=TwoWay}" />
<CheckBox x:Name="uiAlwaysStartInTray"
<CheckBox x:Name="uiAlwaysStartInTray" Margin="0,-3"
Content="start CompactGUI in system tray"
IsChecked="{Binding AppSettings.StartInSystemTray}" />

</StackPanel>
<Separator Margin="0,5,0,5" />

<Label Content="Maximum Compression Threads" FontWeight="SemiBold" />

<StackPanel Orientation="Horizontal" Margin="15,0,15,0">

<Slider x:Name="compressionParallelism" Width="130"

IsSnapToTickEnabled="True" LargeChange="1" Maximum="16" Minimum="0"
Orientation="Horizontal" SmallChange="1" TickFrequency="1"
TickPlacement="BottomRight"
Value="{Binding AppSettings.MaxCompressionThreads, Mode=TwoWay}">

</Slider>

<Label Margin="15,5" FontWeight="SemiBold" Content="{Binding AppSettings.MaxCompressionThreads, FallbackValue=0}"/>
<CheckBox x:Name="uiLockHDDToOneThread" Margin="15,0"
Content="HDDs only use 1 thread"
IsChecked="{Binding AppSettings.LockHDDsToOneThread}" />
</StackPanel>



<Separator Margin="0,5,0,5" />

<Label Content="Background Watcher Settings" FontWeight="SemiBold" />
<StackPanel Margin="10,5,0,7">
<CheckBox x:Name="uiEnableBackgroundWatcher"
<CheckBox x:Name="uiEnableBackgroundWatcher" Margin="0,-3"
Content="monitor compressed folders for changes"
IsChecked="{Binding AppSettings.EnableBackgroundWatcher, Mode=TwoWay}">

Expand All @@ -106,9 +129,9 @@
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
<CheckBox x:Name="uiEnableBackgroundAutoCompression"
<CheckBox x:Name="uiEnableBackgroundAutoCompression"
Content="periodically check and keep folders compressed"
Margin="30,0,0,0"
Margin="30,-3,0,-3"
IsChecked="{Binding AppSettings.EnableBackgroundAutoCompression, Mode=TwoWay}">

<i:Interaction.Triggers>
Expand All @@ -119,11 +142,13 @@
</CheckBox>

</StackPanel>


<Separator Margin="0,5,0,5" />

<Label Content="Updates" FontWeight="SemiBold" />
<StackPanel Margin="10,5,0,7">
<CheckBox x:Name="uiEnablePreReleaseUpdates"
<CheckBox x:Name="uiEnablePreReleaseUpdates" Margin="0,-3"
Content="Check for pre-release updates"
IsChecked="{Binding AppSettings.EnablePreReleaseUpdates}" />

Expand All @@ -134,7 +159,7 @@
<Label Content="UI Scaling" FontWeight="SemiBold" />

<Slider x:Name="uiScalingFactor"
Margin="15,5,15,20"
Margin="15,0,15,0"
IsSnapToTickEnabled="True" LargeChange="0.125" Maximum="1.5" Minimum="0.5"
Orientation="Horizontal" SmallChange="0.125" TickFrequency="0.125"
TickPlacement="BottomRight"
Expand All @@ -149,7 +174,9 @@
</i:Interaction.Triggers>
</Slider>


<Separator Margin="0,0,0,30" />

<Grid HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
Expand Down

0 comments on commit f000abe

Please sign in to comment.