EventChart 2022.5.30

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b6e9b221c77c9b657e64b9d5c2389b76509d51d7fdfb1a098a59c79c15918ca2
4
+ data.tar.gz: 2aaaf35571613983885231c12fbc49be2654ddfbdecc462770f032b940bc7218
5
+ SHA512:
6
+ metadata.gz: 78ce77d93f4f9680f31124a7ccefd4f9d172b1a2c3f1ec9a02ab9af3b0a2188edbafe7e69286ddc074f477506e48c126ec5285baa72b354d74af2711a94f7ad7
7
+ data.tar.gz: 2d2451704e1253ef29d9ea750d6cb841c052bb729350732e028536387ccec5acc16e2fe4cf272e79c1043fccdb41bc3621503c632f422e2d1a78338532f2a3d2
data/bin/eventchart ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'extremeunzip.zzaqsu'
4
+
5
+ if ARGV.empty? # 未指定命令行参数。
6
+ else # 指定了命令行参数。
7
+ returnCode = 0 # 失败
8
+ $rootPath = ARGV[0] # 记录要打包的目录树的根目录。
9
+
10
+ exuzObject = ExtremeUnZip.new # 解压对象
11
+
12
+ result = exuzObject.exuz($rootPath) # 解压
13
+
14
+ if result # 解压成功
15
+ else # 解压失败
16
+ returnCode = 1 # 失败
17
+ end #if result # 解压成功
18
+
19
+ exit returnCode # 退出
20
+ end
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'victoriafresh'
4
+ require 'cbor'
5
+ require 'lzma'
6
+ require 'get_process_mem'
7
+
8
+ class ExtremeUnZip
9
+ # 解压
10
+ def exuz(rootPath)
11
+ result = true # 解压结果
12
+
13
+ currentBlockFile = File.new(rootPath, 'rb') # 打开文件
14
+
15
+ @wholeFileContent = currentBlockFile.read # 读取全部内容
16
+
17
+ currentBlockFile.close # 关闭文件
18
+
19
+ wholeCborByteArray = @wholeFileContent # 从第5个到末尾
20
+
21
+ begin # 可能出错。
22
+ options = {:tolerant => true}
23
+
24
+ wholeCbor = CBOR.decode(wholeCborByteArray, options) # 解码
25
+
26
+ puts wholeCbor
27
+
28
+ result =true # 解压成功
29
+ rescue EOFError => e # 文件内容提前到末尾。一般是压缩包文件未传输完全 。
30
+ puts "Error: the exz file may be incomplete." # 报告错误。文件可能不完整。
31
+
32
+ result = false # 失败
33
+ end #begin # 可能出错。
34
+ end # def exuz(rootPath)
35
+ end # class ExtremeUnZip
@@ -0,0 +1,322 @@
1
+ #!/usr/bin/ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'victoriafresh'
5
+ require 'cbor' # CBOR
6
+ require 'lzma' # LZMA
7
+ require 'etc' # cpu amount
8
+ require 'cod'
9
+ require 'uuid'
10
+ require 'get_process_mem'
11
+ require 'pathname'
12
+
13
+ def checkMemoryUsage(lineNumber)
14
+ mem = GetProcessMem.new
15
+
16
+ puts("#{lineNumber} , Memory: #{mem.mb}, process id: #{Process.pid}"); # Debug
17
+ end # def checkMemoryUsage
18
+
19
+ class ExtremeZip
20
+ def initialize
21
+ @wholeCbor = {} # 整个CBOR结构
22
+ @vfsDataList = [] # 数据块压缩块列表
23
+ @filePartCounter = 0 # 文件分块计数器
24
+ @responsePipeList = [] # 任务回复管道列表
25
+ @processIdList = [] # 子进程编号列表。
26
+ @processTimestamp = Time.new.to_i # 记录进程启动的时间戳。
27
+
28
+ @maxSubProcessAmount = Etc.nprocessors # 获取最大的子进程个数
29
+
30
+ @dataBlockLength = 33554432 # 数据块单元长度, 32MiB
31
+
32
+ @clipDownloader = VictoriaFresh.new # 创建下载器。
33
+
34
+ @clipDownloader.diskFlush = true # 向磁盘写入缓存
35
+ @clipDownloader.diskMultiFile = true # 写多个磁盘文件
36
+ @clipDownloader.diskFileName = 'victoriafreshdata.v.' # 磁盘文件名前缀
37
+ @clipDownloader.diskFlushSize = @dataBlockLength # 磁盘文件大小
38
+ @clipDownloader.ignoreFileName= '.exzignore' # 设置用于指定忽略文件列表的文件名。
39
+ end # def initialize
40
+
41
+ # 压缩目录数据。
42
+ def compressVfsMenu(victoriaFresh)
43
+ replyByteArray = victoriaFresh.to_cbor # #打包成字节数组。
44
+
45
+ # 压缩目录数据并放入CBOR:
46
+ compressedVfsMenu = LZMA.compress(replyByteArray) # 压缩目录数据
47
+
48
+ @wholeCbor['vfsMenu'] = compressedVfsMenu # 加入目录
49
+ end # compressVfsMenu(victoriaFresh) # 压缩目录数据。
50
+
51
+ # 加入基本文件信息
52
+ def addBasicFileInformation
53
+ @wholeCbor['version'] = 251 # 文件格式版本号
54
+
55
+ uuid = UUID.new # 获取生成器
56
+ @wholeCbor['uuid'] = uuid.generate # 指定本个压缩包的唯一编号
57
+
58
+ @wholeCbor['website']='https://rubygems.org/gems/EXtremeZip' # 加入网站地址
59
+
60
+ @wholeCbor['vfsDataListStart']=198910 # 压缩 VFS 数据列表起始位置。
61
+ end # addBasicFileInformation # 加入基本文件信息
62
+
63
+ def writeStamp(rootPath) # 更新时间戳文件
64
+ directoryPathName=Pathname.new(rootPath) #构造路径名字对象。
65
+ datastore= "#{directoryPathName.expand_path}/.exzstamp" # 配置文件路径
66
+ puts "writing stamp file: #{datastore}" # Debug
67
+
68
+ #stamp = wholeCbor['timestamp'] # 获取时间戳
69
+ stampCbor={} # 时间戳对象。
70
+ stampCbor['timestamp']= @processTimestamp # 设置时间戳。
71
+
72
+ compressed= stampCbor.to_cbor
73
+
74
+ extremeZipOutputFile = File.new(datastore, 'wb') # 创建文件
75
+ extremeZipOutputFile.syswrite(compressed) # 写入文件
76
+ extremeZipOutputFile.close # 关闭文件
77
+
78
+ end # writeStamp # 更新时间戳文件
79
+
80
+ def loadStamp(rootPath) # 读取时间戳阈值。
81
+ stamp=0 # 默认值。
82
+ fileExists=false # 文件是否存在
83
+
84
+ directoryPathName=Pathname.new(rootPath) #构造路径名字对象。
85
+
86
+ isFile=directoryPathName.file? #是否是文件。
87
+
88
+ unless isFile #是文件就跳过。
89
+ #陈欣
90
+
91
+ datastore= "#{directoryPathName.expand_path}/.exzstamp" # 配置文件路径
92
+ puts "reading stamp file: #{datastore}" # Debug
93
+
94
+ begin # 尝试读取。
95
+
96
+ #陈欣
97
+
98
+ currentBlockFile = File.new(datastore, 'rb') # 打开文件
99
+
100
+ fileExists=true # 文件存在
101
+
102
+ stampFileContent = currentBlockFile.read # 读取全部内容
103
+
104
+ currentBlockFile.close # 关闭文件
105
+
106
+ options = {:tolerant => true}
107
+
108
+ wholeCbor = CBOR.decode(stampFileContent, options) # 解码
109
+
110
+ puts wholeCbor # Debug
111
+ puts wholeCbor.inspect # Debug
112
+
113
+ stamp = wholeCbor['timestamp'].to_i # 获取时间戳
114
+ rescue Errno::ENOENT, TypeError
115
+ end
116
+ end #unless isFile #是文件就跳过。
117
+
118
+ return stamp, fileExists # 返回时间戳。
119
+ end #loadStamp(rootPath) # 读取时间戳阈值。
120
+
121
+ # 压缩
122
+ def exz(rootPath)
123
+ timestampTHreshold, fileExists=loadStamp(rootPath) # 读取时间戳阈值。
124
+
125
+ puts "threshold: #{timestampTHreshold}" # Debug
126
+
127
+ #陈欣
128
+
129
+ if (timestampTHreshold > 0) # 有效的时间戳
130
+ @clipDownloader.timestampThreshold=timestampTHreshold # 设置文件时间戳阈值。
131
+ end #if (timestampTHreshold > 0) # 有效的时间戳
132
+
133
+ puts "threshold vfs: #{@clipDownloader.timestampThreshold}" # Debug
134
+
135
+ if fileExists # 存在文件,则表明将要发生增量压缩
136
+ @wholeCbor['incremental']=true # 是增量压缩。
137
+ end # if fileExists # 存在文件,则表明用户要求增量压缩
138
+
139
+ @wholeCbor['timestamp']=@processTimestamp # 记录进程启动的时间戳。
140
+
141
+ victoriaFresh, = @clipDownloader.checkOnce(rootPath) # 打包该目录树。
142
+
143
+ @filePartAmount = @clipDownloader.currentDiskFlushSuffix # 获取文件个数
144
+
145
+ compressVfsMenu(victoriaFresh) # 压缩目录数据。
146
+
147
+ addBasicFileInformation # 加入基本文件信息
148
+
149
+ processIdList, responsePipeList = launchSubProcesses # 启动子进程。
150
+
151
+ receiveCompressedVfsDataList(processIdList, responsePipeList) # 接收压缩后的数据块列表
152
+
153
+ checkMemoryUsage(155)
154
+ @wholeCbor['vfsDataList'] = @vfsDataList # 加入数据
155
+
156
+ wholeFileContent = 'exz' + "\0" + @wholeCbor.to_cbor # 追加CBOR字节数组
157
+
158
+ vfsDataListStart=wholeFileContent.length # 按照现在的序列化情况,计算出来的起始位置。
159
+
160
+ while (vfsDataListStart!=@wholeCbor['vfsDataListStart']) # 计算出的偏移不一致
161
+ @wholeCbor['vfsDataListStart']=vfsDataListStart # 使用新的值
162
+ wholeFileContent = 'exz' + "\0" + @wholeCbor.to_cbor # 追加CBOR字节数组
163
+ vfsDataListStart=wholeFileContent.length # 按照现在的序列化情况,计算出来的起始位置。
164
+ end
165
+
166
+ # 写入文件:
167
+ writeFile(wholeFileContent, victoriaFresh) # 写入文件内容
168
+
169
+ appendVfsDataList victoriaFresh # 追加压缩块列表数据。
170
+
171
+ if fileExists # 存在文件,则表明将要发生增量压缩
172
+ writeStamp (rootPath) # 更新时间戳文件
173
+ end # if fileExists # 存在文件,则表明用户要求增量压缩
174
+
175
+ end # def exz(rootPath)
176
+
177
+ # 写入压缩块文件
178
+ def writeCompressBlock(compressed, processCounter)
179
+ extremeZipOutputFile = File.new("comressed.#{processCounter}.cex", 'wb') # 创建文件
180
+ extremeZipOutputFile.syswrite(compressed) # 写入文件
181
+ extremeZipOutputFile.close # 关闭文件
182
+ end
183
+
184
+ # 追加压缩块列表数据。
185
+ def appendVfsDataList (victoriaFresh)
186
+ extremeZipOutputFile = File.new("#{victoriaFresh['name']}.exz", 'ab') # 打开文件
187
+
188
+ processCounter=0 # 块计数器。
189
+
190
+ @wholeCbor['vfsDataList'].each do
191
+ #extremeZipOutputFile = File.new("comressed.#{processCounter}.cex", 'wb') # 创建文件
192
+
193
+ currentBlockFile = File.new("comressed.#{processCounter}.cex", 'rb') # 打开文件
194
+
195
+ wholeFileContent = currentBlockFile.read # 读取全部内容
196
+
197
+ currentBlockFile.close # 关闭文件
198
+ File.delete(currentBlockFile) # 删除数据块文件
199
+
200
+ #wholeFileContent=File.read("comressed.#{processCounter}.cex", 'rb') # 读取压缩块。
201
+
202
+ puts "wirte file contetn length: #{wholeFileContent.length}" # Debghu
203
+
204
+ extremeZipOutputFile.syswrite(wholeFileContent) # 写入文件
205
+
206
+ processCounter += 1 # 计数
207
+ end
208
+
209
+ extremeZipOutputFile.close # 关闭文件
210
+ end
211
+
212
+ # 写入文件内容
213
+ def writeFile(wholeFileContent, victoriaFresh)
214
+ extremeZipOutputFile = File.new("#{victoriaFresh['name']}.exz", 'wb') # 创建文件
215
+ extremeZipOutputFile.syswrite(wholeFileContent) # 写入文件
216
+ extremeZipOutputFile.close # 关闭文件
217
+ end # writeFile(wholeFileContent, victoriaFresh) #写入文件内容
218
+
219
+ # 接收压缩后的数据块列表
220
+ def receiveCompressedVfsDataList(processIdList, responsePipeList)
221
+ processCounter = 0 # 子进程计数器
222
+
223
+ while (processCounter<@filePartAmount) # 并不是所有分块都被处理完毕了。
224
+ currentSubProcess=processIdList[processCounter] # 获取子进程对象
225
+ #processIdList.each do |currentSubProcess|
226
+ compressed = receiveFromSubProcess(currentSubProcess, responsePipeList, processCounter) # 从子进程中读取数据,并终止子进程
227
+
228
+ #写入当前压缩块到文件系统中去作为缓存。陈欣
229
+ writeCompressBlock(compressed, processCounter) # 写入压缩块文件
230
+
231
+ blockInfo={} # 块信息
232
+ blockInfo['length']=compressed.length # 记录长度
233
+
234
+ puts "block length: #{blockInfo['length']}" # Debug
235
+
236
+ @vfsDataList << blockInfo # 加入数据块列表中
237
+ checkMemoryUsage(150)
238
+
239
+ processCounter += 1 # 子进程计数
240
+
241
+ if (@filePartCounter<@filePartAmount) # 还有一些分块尚未交给子进程进行处理
242
+ schedule1Block(@filePartCounter) # 再启动一个子进程
243
+ end # if (@filePartCounter<@filePartAmount) # 还有一些分块尚未交给子进程进行处理
244
+ end # processIdList.each do |currentSubProcess|
245
+ end # receiveCompressedVfsDataList # 接收压缩后的数据块列表
246
+
247
+ # 读取块文件内容
248
+ def readBlockFile(filePartCounter)
249
+ currentBlockFile = File.new(@clipDownloader.diskFileName + filePartCounter.to_s, 'rb') # 打开文件
250
+
251
+ currentBlockData = currentBlockFile.read # 读取全部内容
252
+
253
+ currentBlockFile.close # 关闭文件
254
+
255
+ File.delete(currentBlockFile) # 删除数据块文件
256
+
257
+ currentBlockData
258
+ end
259
+
260
+ # 计划一个块的压缩计算
261
+ def schedule1Block(filePartCounter)
262
+ currentBlockData = readBlockFile(filePartCounter) # 读取块文件内容
263
+
264
+ currentResponsePipe = Cod.pipe # 任务回复管道
265
+
266
+ p1 = fork do # 复制出子进程
267
+ compressInSubProcess(currentBlockData, currentResponsePipe) # 在子进程中具体执行的压缩代码
268
+ end # p1 = fork do #复制出子进程
269
+
270
+ # processDataLength += @dataBlockLength # 计数
271
+ checkMemoryUsage(130)
272
+
273
+ # 记录管道:
274
+ # taskPipeList << currentTaskPipe
275
+ @responsePipeList << currentResponsePipe # 记录回复管道
276
+
277
+ @processIdList << p1 # 记录到子进程列表中
278
+
279
+ @filePartCounter += 1 # 计数
280
+
281
+ [currentResponsePipe, p1]
282
+ end # schedule1Block(filePartCounter) # 计划一个块的压缩计算
283
+
284
+ # 启动子进程。
285
+ def launchSubProcesses
286
+ while ((@filePartCounter < @filePartAmount) && (@filePartCounter<@maxSubProcessAmount)) # 未处理完毕,并且未达到最大子进程个数
287
+ currentResponsePipe, p1 = schedule1Block(@filePartCounter) # 计划一个块的压缩计算
288
+ end # while processDataLength < victoriaFreshData.byte_size do #未处理完毕
289
+
290
+ [@processIdList, @responsePipeList]
291
+ end # launchSubProcesses # 启动子进程。
292
+
293
+ # 在子进程中具体执行的压缩代码
294
+ def compressInSubProcess(currentBlockData, currentResponsePipe)
295
+ checkMemoryUsage(115) # Debug
296
+ currentBlockDataToCompress = currentBlockData # 读取数据块
297
+
298
+ currentCompressedVfsData = LZMA.compress(currentBlockDataToCompress) # 压缩当前块
299
+
300
+ checkMemoryUsage(120)
301
+ puts("compressed data length: #{currentCompressedVfsData.bytesize}") # Debug.
302
+
303
+ currentResponsePipe.put currentCompressedVfsData # 将压缩后的数据块写入到回复管道中
304
+
305
+ puts("finished #{Process.pid}") # Debug
306
+ end # compressInSubProcess(currentBlockData, currentResponsePipe) # 在子进程中具体执行的压缩代码
307
+
308
+ # 从子进程中读取数据,并终止子进程
309
+ def receiveFromSubProcess(currentSubProcess, responsePipeList, processCounter)
310
+ puts("waiting #{currentSubProcess}") # Debug
311
+ checkMemoryUsage(140)
312
+
313
+ currentResponsePipe = responsePipeList[processCounter] # 任务回复管道
314
+
315
+ currentCompressedVfsDataFromSubProcess = currentResponsePipe.get # 读取压缩后数据
316
+ checkMemoryUsage(145)
317
+
318
+ Process.waitpid(currentSubProcess) # 等待该个子进程
319
+
320
+ currentCompressedVfsDataFromSubProcess
321
+ end # receiveFromSubProcess(currentSubProcess) # 从子进程中读取数据,并终止子进程
322
+ end # class ExtremeZip
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: EventChart
3
+ version: !ruby/object:Gem::Version
4
+ version: 2022.5.30
5
+ platform: ruby
6
+ authors:
7
+ - Hxcan Cai
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-05-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cod
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.6.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.6.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: get_process_mem
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.2.7
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.2.7
41
+ - !ruby/object:Gem::Dependency
42
+ name: ruby-lzma
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 0.4.3
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 0.4.3
55
+ - !ruby/object:Gem::Dependency
56
+ name: notifier
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 0.5.2
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 0.5.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: uuid
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 2.3.9
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 2.3.9
83
+ - !ruby/object:Gem::Dependency
84
+ name: VictoriaFreSh
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 2022.2.24
90
+ - - "~>"
91
+ - !ruby/object:Gem::Version
92
+ version: 2022.2.24
93
+ type: :runtime
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: 2022.2.24
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: 2022.2.24
103
+ - !ruby/object:Gem::Dependency
104
+ name: hx_cbor
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 2021.8.20
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: 2021.8.20
117
+ description: EventChart
118
+ email: caihuosheng@gmail.com
119
+ executables:
120
+ - eventchart
121
+ extensions: []
122
+ extra_rdoc_files: []
123
+ files:
124
+ - bin/eventchart
125
+ - lib/extremeunzip.zzaqsu.rb
126
+ - lib/extremezip.zzaqsv.rb
127
+ homepage: http://rubygems.org/gems/EventChart
128
+ licenses:
129
+ - MIT
130
+ metadata: {}
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubygems_version: 3.0.9
147
+ signing_key:
148
+ specification_version: 4
149
+ summary: EventChart
150
+ test_files: []