#Region "Microsoft.VisualBasic::2a8d2c4ab4b6fd68150161b33a111f44, Distribute_computing\GridDynamics_plugins\IO\PopulationZip.vb" ' Author: ' ' asuka (amethyst.asuka@gcmodeller.org) ' xie (genetics@smrucc.org) ' xieguigang (xie.guigang@live.com) ' ' Copyright (c) 2018 GPL3 Licensed ' ' ' GNU GENERAL PUBLIC LICENSE (GPL3) ' ' ' 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 . ' /********************************************************************************/ ' Summaries: ' Class PopulationZip ' ' Properties: Count ' ' Constructor: (+1 Overloads) Sub New ' ' Function: GetIndividual ' ' Sub: (+2 Overloads) Add, OrderBy, Trim ' ' /********************************************************************************/ #End Region Imports System.IO Imports System.IO.Compression Imports System.Runtime.CompilerServices Imports Microsoft.VisualBasic.ApplicationServices.Zip Imports Microsoft.VisualBasic.Language Imports Microsoft.VisualBasic.Linq Imports Microsoft.VisualBasic.MachineLearning.Darwinism.GAF Imports Microsoft.VisualBasic.MachineLearning.Darwinism.NonlinearGridTopology ''' ''' 使用zip压缩的形式,将population保存为临时文件 ''' Public Class PopulationZip : Inherits PopulationCollection(Of Genome) ReadOnly target$ ReadOnly chunkSize% ReadOnly mutationRate As Double, truncate As Double Dim index As VBInteger = Scan0 ''' ''' [index => md5] ''' Dim indexHashMaps As New Dictionary(Of String, String) Public Overrides ReadOnly Property Count As Integer Get Return index End Get End Property Default Public Overrides ReadOnly Property Item(index As Integer) As Genome Get Dim genome As New Genome(GetIndividual(index), mutationRate, truncate) indexHashMaps(index.ToString) = genome.ToString Return genome End Get End Property ''' ''' The target zip file ''' ''' Sub New(target$, mutationRate As Double, truncate As Double, Optional chunkSize% = 20480) Me.target = target Me.chunkSize = chunkSize Me.mutationRate = mutationRate Me.truncate = truncate Call target.DeleteFile End Sub Public Overloads Sub Add(genome As GridSystem) Dim temp = App.GetAppSysTempFile($".grid/{++index}", App.PID, "population_") Using file As FileStream = temp.Open Call genome.Serialize(file, chunkSize:=chunkSize) End Using Call ZipLib.AddToArchive( files:={temp}, archiveFullName:=target, action:=ArchiveAction.Merge, fileOverwrite:=Overwrite.Always, compression:=CompressionLevel.Fastest ) Call temp.DeleteFile End Sub Public Overrides Sub Add(chr As Genome) Call Add(chr.chromosome) End Sub Public Overrides Sub Trim(capacitySize As Integer) If capacitySize = Count Then Return End If ' 将capacitysize后面的序号的genome全部删除 Dim names = (Count - capacitySize).Sequence _ .Select(Function(i) i + capacitySize) _ .Select(Function(i) CStr(i)) _ .ToArray index = capacitySize Using zip As ZipArchive = ZipFile.Open(target, ZipArchiveMode.Update) Call zip.DeleteItems(names) End Using End Sub Public Overrides Sub OrderBy(fitness As Func(Of String, Double)) Dim tempZip As String = App.GetAppSysTempFile(".zip", App.PID) Using zip As ZipArchive = ZipFile.Open(target, ZipArchiveMode.Read) Dim orderEntries = zip.Entries.OrderBy(Function(e) fitness(indexHashMaps(e.Name))).ToArray Dim i As VBInteger = Scan0 Using temporder As ZipArchive = ZipFile.Open(tempZip, ZipArchiveMode.Create) For Each entry In orderEntries Dim newEntry = temporder.CreateEntry(++i, CompressionLevel.Fastest) Using a = entry.Open, b = newEntry.Open Call a.CopyTo(b) End Using Next End Using End Using Call target.DeleteFile Call tempZip.FileMove(target) End Sub Public Function GetIndividual(i As Integer) As GridSystem Dim buffer As MemoryStream = ZipStreamReader.GetZipSubStream(target, CStr(i)) If buffer Is Nothing Then Throw New MissingMemberException(i) Else Using buffer Return buffer.LoadGridSystem End Using End If End Function End Class