VictoriaFreSh 2022.1.15 → 2022.2.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/victoriafresh.rb +162 -146
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a021bf4ba7e3c19fe3d303849da3fdbd5410f8188af87059e1ca404d77450bf8
4
- data.tar.gz: 986f3fea84eb15ce0574edbfd6bb9247d00b9002e98080228d5b2c6a79283e53
3
+ metadata.gz: 5293fd04253e9ab289f8827edf268ea5653d709402de849d5304ea19fc014a10
4
+ data.tar.gz: c5aa96e8dd2a479a3d80b411299ae22c8d49f18fa20c3ad051913bbc375ba243
5
5
  SHA512:
6
- metadata.gz: d27b6fead18004368e8948f4e440b213874fe8edcf67b49a86f0ae7046c939125a035db420c865af3c5014f11fa3fb0df262ebc774199edbc043535f41fdfa0e
7
- data.tar.gz: 7af520afdca24160b014aaeb3995f05418f09319df854d969f48b8e5c4319756336e1b4a886681d844a51d596dc1f2e49afdd419510a1af92eb3ae8aa10eba7a
6
+ metadata.gz: 39014b2e4a571cb0c8da0ddcc7f7d4c0ef4b41a3d61405ed519391d2bc6054d1686e1443be27701e31bd5eb995c99c95e98b465ff6c380b663a34caba6be6d0a
7
+ data.tar.gz: 12f6a697b3b4d761cd713e26257e9e4901cd8da3ecbeff5358ae88e1fa0be97ae2f5f451423b9c509859c70c1c5edd78e96ee43dbf9e0bd528a75b931d742be5
data/lib/victoriafresh.rb CHANGED
@@ -9,29 +9,31 @@ require 'digest'
9
9
  # require File.dirname(__FILE__)+'/VictoriaFreSh/filemessage_pb.rb'
10
10
 
11
11
  class VictoriaFresh
12
- attr_accessor :diskFlushSize #累积了这么多的数据就向磁盘写入,以减少内存占用
13
- attr_accessor :diskFileName #向磁盘写入数据时的文件名或前缀
14
- attr_accessor :ignoreFileName # 用于指定忽略文件名列表的配置文件的名字
15
- attr_accessor :diskMultiFile #向磁盘写入时,是否要写多个文件
16
- attr_accessor :diskFlush #要提前磁盘写入文件,以节省内存吗?
17
- attr_accessor :currentDiskFlushSuffix #当前的文件后缀。也等价于已经写入的文件片段个数
12
+ attr_accessor :diskFlushSize #累积了这么多的数据就向磁盘写入,以减少内存占用
13
+ attr_accessor :diskFileName #向磁盘写入数据时的文件名或前缀
14
+ attr_accessor :ignoreFileName # 用于指定忽略文件名列表的配置文件的名字
15
+ attr_accessor :diskMultiFile #向磁盘写入时,是否要写多个文件
16
+ attr_accessor :diskFlush #要提前磁盘写入文件,以节省内存吗?
17
+ attr_accessor :currentDiskFlushSuffix #当前的文件后缀。也等价于已经写入的文件片段个数
18
+ attr_accessor :timestampThreshold # 文件时间戳阈值。早于这个时间戳的文件不被放入数据块
18
19
 
19
- def initialize
20
- @diskFlush=false #要向磁盘写入文件
21
- @diskFlushSize=143212 #磁盘分块大小
22
- @diskFileName='victoriafreshdata.v' #磁盘文件名
23
- @ignoreFileName=nil # 忽略文件名列表配置文件名
24
- @diskMultiFile=false #磁盘整个文件,不是多个文件
25
- @diskWriteFileObject={} #向磁盘写入文件的对象
26
- @contentString="" #内容字符串
27
- @contentPartArray=[] #内容片段数组
28
- @currentDiskFlushSuffix=0 #当前的磁盘文件后缀
29
- @bufferLength=0 #缓冲区总长度
30
- @externalDataFile={} #外部数据文件对象
31
- @nextFileIdToUse=1 # 下一个要用的文件编号。
32
- @md5FileIdMap={} # MD5 与文件编号之间的映射
33
- @fileIdPathMap={} # 文件编号与它的实际路径之间的映射
34
- end
20
+ def initialize
21
+ @diskFlush=false #要向磁盘写入文件
22
+ @diskFlushSize=143212 #磁盘分块大小
23
+ @diskFileName='victoriafreshdata.v' #磁盘文件名
24
+ @ignoreFileName=nil # 忽略文件名列表配置文件名
25
+ @diskMultiFile=false #磁盘整个文件,不是多个文件
26
+ @diskWriteFileObject={} #向磁盘写入文件的对象
27
+ @contentString="" #内容字符串
28
+ @contentPartArray=[] #内容片段数组
29
+ @currentDiskFlushSuffix=0 #当前的磁盘文件后缀
30
+ @bufferLength=0 #缓冲区总长度
31
+ @externalDataFile={} #外部数据文件对象
32
+ @nextFileIdToUse=1 # 下一个要用的文件编号。
33
+ @md5FileIdMap={} # MD5 与文件编号之间的映射
34
+ @fileIdPathMap={} # 文件编号与它的实际路径之间的映射
35
+ @timestampThreshold=0 # 默认时间戳阈值是0,所有文件都被放入数据块。
36
+ end
35
37
 
36
38
  # 计算文件内容的MD5。
37
39
  def calculateMd5(currentFileContent)
@@ -346,10 +348,9 @@ class VictoriaFresh
346
348
 
347
349
  @diskWriteFileObject.close
348
350
  else #单个磁盘文件
349
- @diskWriteFileObject.syswrite(contentToWrite) #写入内容
350
-
351
- @diskWriteFileObject.close #关闭文件
352
-
351
+ @diskWriteFileObject.syswrite(contentToWrite) #写入内容
352
+
353
+ @diskWriteFileObject.close #关闭文件
353
354
  end #if (@diskMultiFile) #多个磁盘文件
354
355
  end #if (isFinalPart) #是最后一部分
355
356
  end #if (@diskFlush) #要做磁盘写入
@@ -358,145 +359,160 @@ class VictoriaFresh
358
359
  # 读取要忽略的文件名列表。
359
360
  def readIgnoreFileList (directoryPathName)
360
361
  current_paragraph=[] # 列表
361
- #陈欣
362
- datastore= "#{directoryPathName.expand_path}/#{@ignoreFileName}" # 配置文件路径
363
- puts "reading ignore file: #{datastore}" # Debug
364
362
 
365
- begin
366
- File.foreach(datastore).with_index do |line, _line_num|
367
- puts line.to_s # Debug
368
- puts "#{line.empty?} #{line.length} #{line.strip.empty?}" # Debug
369
-
370
- if line.strip.empty? # 空行
371
- else # 不是空行
372
- current_paragraph << line.strip # 记录一行
373
- end # if line.strip.empty? # 空行
374
- end # File&.foreach(datastore).with_index do |line, _line_num|
375
-
376
- rescue Errno::ENOENT
377
- end
363
+ if @ignoreFileName # 设置了忽略列表
364
+ #陈欣
365
+ datastore = "#{directoryPathName.expand_path}/#{@ignoreFileName}" # 配置文件路径
366
+
367
+ begin
368
+ File.foreach(datastore).with_index do |line, _line_num|
369
+ if line.strip.empty? # 空行
370
+ else # 不是空行
371
+ current_paragraph << line.strip # 记录一行
372
+ end # if line.strip.empty? # 空行
373
+ end # File&.foreach(datastore).with_index do |line, _line_num|
374
+ rescue Errno::ENOENT
375
+ end
376
+ end # if @ignoreFileName # 设置了忽略列表
378
377
 
379
- puts "ignore list: #{current_paragraph}" # Debug
380
378
  current_paragraph
381
379
  end
380
+
381
+ def timestampTooEarly(subFile) # 是否文件时间过早。
382
+ result=false # 结果。
383
+ directoryPathName=subFile # 获取路径对象。
384
+ #isFile=directoryPathName.file? #是否是文件。
385
+ #isSymLink=directoryPathName.symlink? #是否是符号链接
386
+ isDirectory=directoryPathName.directory? # 是否是目录。
387
+
388
+ unless isDirectory # 如果是目录就跳过
389
+ #记录时间戳:
390
+ directoryPath=directoryPathName.expand_path # 获取完整路径。
391
+ mtimeStamp=File.mtime(directoryPath) #获取时间戳
392
+
393
+ fileTimestamp=mtimeStamp.tv_sec # 获取秒数
394
+
395
+ #puts "path: #{directoryPath}, time stamp: #{fileTimestamp}, threshold: #{@timestampThreshold}" # debug
396
+
397
+ if (fileTimestamp< @timestampThreshold) # 文件的时间戳比阈值要小,过早了
398
+ result =true # 是过早了
399
+ end # if (fileTimestamp< @timestampThreshold) # 文件的时间戳比阈值要小,过早了
400
+ end # unless isDirectory # 如果是目录就跳过
401
+
402
+ result # 返回结果
403
+ end # def timestampTooEarly(subFile)) # 是否文件时间过早。
382
404
 
383
405
  def checkOnce(directoryPath, startIndex=0, layer=0) #打包一个目录树。
384
- if (@diskFlush) #要向磁盘写入文件
385
- if (layer==0) #最外层
386
- if (@diskMultiFile) #要写多个文件
387
- else #不写多个文件
388
- @diskWriteFileObject=File.new(@diskFileName, 'wb') #打开文件
389
- end #if (@diskMultiFile) #要写多个文件
390
- end #if (layer==0) #最外层
391
- end #if (@diskFlush) #要向磁盘写入文件s
406
+ if (@diskFlush) #要向磁盘写入文件
407
+ if (layer==0) #最外层
408
+ if (@diskMultiFile) #要写多个文件
409
+ else #不写多个文件
410
+ @diskWriteFileObject=File.new(@diskFileName, 'wb') #打开文件
411
+ end #if (@diskMultiFile) #要写多个文件
412
+ end #if (layer==0) #最外层
413
+ end #if (@diskFlush) #要向磁盘写入文件s
414
+
415
+ packagedFile={} #创建文件消息对象。
416
+
417
+ directoryPathName=Pathname.new(directoryPath) #构造路径名字对象。
418
+
419
+ baseName=directoryPathName.basename.to_s #基本文件名。
420
+
421
+ packagedFile['name']=baseName #设置文件名。
422
+
423
+ isFile=directoryPathName.file? #是否是文件。
424
+ isSymLink=directoryPathName.symlink? #是否是符号链接
425
+
426
+ packagedFile['is_file']=isFile #设置属性,是否是文件。
427
+ packagedFile['file_start_index']=startIndex #记录文件内容的开始位置。
428
+
429
+ packagedFile['is_symlink']=isSymLink #设置属性,是否是符号链接
392
430
 
393
- packagedFile={} #创建文件消息对象。
431
+ #记录时间戳:
432
+ begin #读取时间戳
433
+ mtimeStamp=File.mtime(directoryPath) #获取时间戳
394
434
 
395
- directoryPathName=Pathname.new(directoryPath) #构造路径名字对象。
435
+ packagedFile['timestamp']={} #时间戳
436
+ packagedFile['timestamp']['seconds']=mtimeStamp.tv_sec #设置秒数
437
+ packagedFile['timestamp']['nanos']=mtimeStamp.tv_nsec #设置纳秒数
396
438
 
397
- baseName=directoryPathName.basename.to_s #基本文件名。
439
+ packagedFile['permission']=(File.stat(directoryPath).mode & 07777 ) #设置权限信息
440
+ rescue Errno::ENOENT
441
+ rescue Errno::EACCES #权限受限
442
+ end #begin #读取时间戳
398
443
 
399
- packagedFile['name']=baseName #设置文件名。
444
+ if isFile #是文件,不用再列出其子文件了。
445
+ packagedFile['file_length']=0 #记录文件的内容长度。
446
+ packagedFile['id']= nextFileId # 设置下一个文件编号
400
447
 
401
- isFile=directoryPathName.file? #是否是文件。
402
- isSymLink=directoryPathName.symlink? #是否是符号链接
448
+ #读取文件内容:
449
+ fileToReadContent=File.new(directoryPath,"rb") #创建文件。
450
+ currentFileContent=fileToReadContent.read #全部读取
451
+ fileToReadContent.close # 关闭文件
403
452
 
404
- packagedFile['is_file']=isFile #设置属性,是否是文件。
405
- packagedFile['file_start_index']=startIndex #记录文件内容的开始位置。
453
+ currentContentMd5=calculateMd5(currentFileContent) # 计算文件内容的MD5。
406
454
 
407
- packagedFile['is_symlink']=isSymLink #设置属性,是否是符号链接
455
+ sameFileId=@md5FileIdMap[currentContentMd5] # 尝试寻找对应的相同文件的编号。
408
456
 
409
- #记录时间戳:
410
- begin #读取时间戳
411
- mtimeStamp=File.mtime(directoryPath) #获取时间戳
412
-
413
- packagedFile['timestamp']={} #时间戳
414
- packagedFile['timestamp']['seconds']=mtimeStamp.tv_sec #设置秒数
415
- packagedFile['timestamp']['nanos']=mtimeStamp.tv_nsec #设置纳秒数
416
-
417
- packagedFile['permission']=(File.stat(directoryPath).mode & 07777 ) #设置权限信息
418
- rescue Errno::ENOENT
419
- rescue Errno::EACCES #权限受限
420
- end #begin #读取时间戳
421
-
422
- if isFile #是文件,不用再列出其子文件了。
423
- packagedFile['file_length']=0 #记录文件的内容长度。
424
- packagedFile['id']= nextFileId # 设置下一个文件编号
425
-
426
- #读取文件内容:
427
- fileToReadContent=File.new(directoryPath,"rb") #创建文件。
428
- currentFileContent=fileToReadContent.read #全部读取
429
-
430
- currentContentMd5=calculateMd5(currentFileContent) # 计算文件内容的MD5。
431
-
432
- sameFileId=@md5FileIdMap[currentContentMd5] # 尝试寻找对应的相同文件的编号。
433
-
434
- if sameFileId.nil? # 不存在相同的文件
435
- packagedFile['file_length']=directoryPathName.size #记录文件的内容长度。
436
-
437
- @contentPartArray << currentFileContent
438
- @bufferLength=@bufferLength+ currentFileContent.length #记录缓冲区总长度
439
- @md5FileIdMap[currentContentMd5]=packagedFile['id'] # 尝试寻找对应的相同文件的编号。
440
- else # 存在相同的文件
441
- packagedFile['is_duplicate']=true # 是重复文件。
442
- packagedFile['same_file_id']=sameFileId # 设置相同文件的编号。
443
- end # if sameFileId.nil? # 不存在相同的文件
444
-
445
- assessDiskFlush(layer) #考虑是否要向磁盘先输出内容
446
- elsif (isSymLink) #是符号链接
447
- linkTarget=directoryPathName.readlink #获取链接目标
448
-
449
- packagedFile['file_length']=linkTarget.to_s.bytesize #记录文件的内容长度。
450
-
451
- #读取文件内容:
452
- # fileToReadContent=File.new(directoryPath,"rb") #创建文件。
453
- currentFileContent=StringIO.new(linkTarget.to_s).binmode.read #全部读取。
454
- @contentPartArray << currentFileContent #加入数组
455
- @bufferLength=@bufferLength + currentFileContent.length #记录缓冲区总长度
456
-
457
- assessDiskFlush(layer) #考虑是否要向磁盘先输出内容
458
- else #是目录。
459
- subFileStartIndex=startIndex #子文件的起始位置,以此目录的起始位置为基准。
460
-
461
- packagedFile['file_length']=0 #本目录的内容长度。
462
- packagedFile['sub_files'] = [] #加入到子文件列表中。
457
+ if sameFileId.nil? # 不存在相同的文件
458
+ packagedFile['file_length']=directoryPathName.size #记录文件的内容长度。
459
+
460
+ @contentPartArray << currentFileContent
461
+ @bufferLength=@bufferLength+ currentFileContent.length #记录缓冲区总长度
462
+ @md5FileIdMap[currentContentMd5]=packagedFile['id'] # 尝试寻找对应的相同文件的编号。
463
+ else # 存在相同的文件
464
+ packagedFile['is_duplicate']=true # 是重复文件。
465
+ packagedFile['same_file_id']=sameFileId # 设置相同文件的编号。
466
+ end # if sameFileId.nil? # 不存在相同的文件
467
+
468
+ assessDiskFlush(layer) #考虑是否要向磁盘先输出内容
469
+ elsif (isSymLink) #是符号链接
470
+ linkTarget=directoryPathName.readlink #获取链接目标
463
471
 
464
- ignoreFileList=readIgnoreFileList(directoryPathName) # 读取要忽略的文件名列表。
465
-
466
- directoryPathName.each_child do |subFile| #一个个文件地处理。
467
- begin
468
- subFilebaseName=subFile.basename.to_s #基本文件名。
469
-
470
- if (ignoreFileList.include?(subFilebaseName)) # 是要忽略的文件
471
- puts "ignore #{subFile}" # 报告,忽略。
472
- else # 不忽略
473
- realPath=subFile.expand_path #获取绝对路径。
474
-
475
- packagedSubFile,subFileContent=checkOnce(realPath,subFileStartIndex, layer+1) #打包这个子文件。
476
-
477
- packagedFile['sub_files'] << packagedSubFile #加入到子文件列表中。
478
-
479
- assessDiskFlush(layer) #考虑是否要向磁盘先输出内容
480
-
481
- subFileStartIndex+=packagedSubFile['file_length'] #记录打包的子文件的长度,更新下一个要打包的子文件的起始位置。
482
-
483
- # puts("237, content string length: #{contentString.length}") #Debug
484
-
485
- packagedFile['file_length']+=packagedSubFile['file_length'] #随着子文件的打包而更新本目录的总长度。
486
-
487
- end
488
-
489
- rescue Errno::EMFILE # File not exist
490
- puts "Rescued by Errno::EMFILE statement. #{subFile}" #报告错误
491
- end
492
- end #directoryPathName.each_child do |subFile| #一个个文件地处理。
493
- end #if (isFile) #是文件,不用再列出其子文件了。
472
+ packagedFile['file_length']=linkTarget.to_s.bytesize #记录文件的内容长度。
494
473
 
495
- # puts("300, contentString: #{contentString}, nil?: #{contentString.nil?}, direcotry path: #{directoryPath}, layer: #{layer}") #Debug
474
+ #读取文件内容:
475
+ # fileToReadContent=File.new(directoryPath,"rb") #创建文件。
476
+ currentFileContent=StringIO.new(linkTarget.to_s).binmode.read #全部读取。
477
+ @contentPartArray << currentFileContent #加入数组
478
+ @bufferLength=@bufferLength + currentFileContent.length #记录缓冲区总长度
496
479
 
480
+ assessDiskFlush(layer) #考虑是否要向磁盘先输出内容
481
+ else #是目录。
482
+ subFileStartIndex=startIndex #子文件的起始位置,以此目录的起始位置为基准。
483
+
484
+ packagedFile['file_length']=0 #本目录的内容长度。
485
+ packagedFile['sub_files'] = [] #加入到子文件列表中。
497
486
 
498
- # puts("302, contentString: #{contentString}, nil?: #{contentString.nil?}, direcotry path: #{directoryPath}, layer: #{layer}") #Debug
487
+ ignoreFileList=readIgnoreFileList(directoryPathName) # 读取要忽略的文件名列表。
499
488
 
489
+ directoryPathName.each_child do |subFile| #一个个文件地处理。
490
+ begin
491
+ subFilebaseName=subFile.basename.to_s #基本文件名。
492
+
493
+ if (ignoreFileList.include?(subFilebaseName)) # 是要忽略的文件
494
+ puts "ignore #{subFile}" # 报告,忽略。
495
+ elsif (timestampTooEarly(subFile)) # 文件时间过早。
496
+ puts "ignore #{subFile} early file" # 报告,忽略。
497
+ else # 不忽略
498
+ realPath=subFile.expand_path #获取绝对路径。
499
+
500
+ packagedSubFile,subFileContent=checkOnce(realPath,subFileStartIndex, layer+1) #打包这个子文件。
501
+
502
+ packagedFile['sub_files'] << packagedSubFile #加入到子文件列表中。
503
+
504
+ assessDiskFlush(layer) #考虑是否要向磁盘先输出内容
505
+
506
+ subFileStartIndex+=packagedSubFile['file_length'] #记录打包的子文件的长度,更新下一个要打包的子文件的起始位置。
507
+
508
+ packagedFile['file_length']+=packagedSubFile['file_length'] #随着子文件的打包而更新本目录的总长度。
509
+ end
510
+ rescue Errno::EMFILE # too many open Files in process
511
+ puts "Rescued by Errno::EMFILE statement. #{subFile}" #报告错误
512
+ end
513
+ end #directoryPathName.each_child do |subFile| #一个个文件地处理。
514
+ end #if (isFile) #是文件,不用再列出其子文件了。
515
+
500
516
  contentToResult="" #要返回的内容
501
517
 
502
518
  if (layer==0) #是最外层
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: VictoriaFreSh
3
3
  version: !ruby/object:Gem::Version
4
- version: 2022.1.15
4
+ version: 2022.2.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hxcan Cai
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-15 00:00:00.000000000 Z
11
+ date: 2022-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hx_cbor