file_writer 0.1.1 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e75512a476ab489dc445ed26b71597714b5c9337
4
- data.tar.gz: 0b6811f8bb36e43994157a34134f723d1912b80e
2
+ SHA256:
3
+ metadata.gz: 50aeafa6cca7a75defbdc12934fd5e453d30dc3cdc6e53fa0484efab3045a6be
4
+ data.tar.gz: 4956aa84d50d48bd3bf71bb982e0509cfbec74126003e8c3db278b0029179834
5
5
  SHA512:
6
- metadata.gz: 22c32936a4a6020bb7a1074d0be3c67e644d18523f4ac11720d2309601812572850fa3b97fdeaee6ff2c90564447bc237be67d4bc44df4ef42ea03692f975b06
7
- data.tar.gz: 64b955399678d05ee7858ee7676d87dc1359414914e411af85178049de3f2110cabb25495b675e4555fe9f0ee9547b067af82c55bd6974332689c6128959a412
6
+ metadata.gz: c20d348d7bb7db67efc89b2ecebafe075c99e53cc6209f9105ea58c6b7e824fca9f071c8e67b0146e3f1ce3eadd387748c431e1d02021e06269c4293d75413c9
7
+ data.tar.gz: 944b96bb826fd877c943a5b2d2e623c9ee3c6cab2e5664aa1d782df049597e01c14e77a9f0042a41faaa9ecfa52668eab09d0abb5dbe37653c8035d7f94e976c
data/.gitignore CHANGED
@@ -7,3 +7,6 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ *~
11
+ *#
12
+ /vendor/
data/file_writer.gemspec CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
23
 
24
- spec.add_development_dependency "bundler", "~> 1.13"
24
+ spec.add_development_dependency "bundler", "~> 2.1.4"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
26
26
  spec.add_development_dependency "rspec", "~> 3.0"
27
27
  end
@@ -1,3 +1,3 @@
1
1
  class FileWriter
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.4"
3
3
  end
data/lib/file_writer.rb CHANGED
@@ -15,23 +15,55 @@ class FileWriter
15
15
  @fname = fname
16
16
  end
17
17
 
18
+ SPLIT_SIZE = 65536
19
+
18
20
  # Overwrite the file
19
21
  #
20
22
  # @param String contents The new contents for the file.
21
23
  #
22
24
  def write(contents)
23
25
  backup = fname + "~"
24
- mode = File.stat(fname).mode
25
26
 
26
- begin
27
- File.rename(fname, backup)
28
- rescue SystemCallError
29
- FileUtils.cp(fname,fname+"~")
27
+ existing = File.exists?(fname)
28
+
29
+ if existing
30
+ fmode = File.stat(fname).mode
31
+ begin
32
+ File.rename(fname, backup)
33
+ rescue SystemCallError
34
+ FileUtils.cp(fname,fname+"~")
35
+ end
36
+ else
37
+ fmode = nil
30
38
  end
31
39
 
32
- File.open(fname, "wb+", mode) do |f|
33
- if f.syswrite(contents) != contents.bytesize
34
- raise SystemCallError.new("FileWriter#write: syswrite returned unexpected length")
40
+ File.open(fname, "wb+", fmode) do |f|
41
+ size = contents.bytesize
42
+
43
+ #
44
+ #We do this rather than f.write or f.syswrite as it
45
+ # gives substantially better latency in a threaded
46
+ # environment as of MRI 2.7.2 than a single write,
47
+ # at the cost of throughput
48
+ #
49
+ # See tests/latency.rb for a test case, and try
50
+ # replacing the below with
51
+ #
52
+ # ```
53
+ # written = File.write(contents)
54
+ # ```
55
+ #
56
+ written = 0
57
+ while (size - written) > SPLIT_SIZE
58
+ if (w = f.write(contents[written .. (written+SPLIT_SIZE-1)])) != SPLIT_SIZE
59
+ raise SystemCallError.new("FileWriter#write: write returned unexpected length (#{w.inspect})")
60
+ end
61
+ written += w
62
+ end
63
+ written += f.write(contents[written .. -1])
64
+
65
+ if written != size
66
+ raise SystemCallError.new("FileWriter#write: write returned unexpected length")
35
67
  end
36
68
  f.flush
37
69
  f.fsync
data/tests/latency.rb ADDED
@@ -0,0 +1,33 @@
1
+ #
2
+ # To test latency on writing large chunks of data in one go
3
+ #
4
+
5
+ $: << "../lib"
6
+
7
+ require 'benchmark'
8
+ require 'file_writer'
9
+
10
+ data = " " * (16_777_216*100 + 42)
11
+ t1 = Thread.new do
12
+ loop do
13
+ FileWriter.write("./test", data)
14
+ end
15
+ end
16
+
17
+ accum = []
18
+ t2 = Thread.new do
19
+ loop do
20
+ b = Benchmark.measure do
21
+ 100000.times do
22
+ " "*1024
23
+ end
24
+ end
25
+ accum << b.total
26
+ break if accum.length > 1000
27
+ end
28
+
29
+ p accum.sum / accum.size
30
+ end
31
+
32
+ t1.join
33
+ t2.join
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: file_writer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vidar Hokstad
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-01-21 00:00:00.000000000 Z
11
+ date: 2022-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.13'
19
+ version: 2.1.4
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.13'
26
+ version: 2.1.4
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -71,6 +71,7 @@ files:
71
71
  - file_writer.gemspec
72
72
  - lib/file_writer.rb
73
73
  - lib/file_writer/version.rb
74
+ - tests/latency.rb
74
75
  homepage: https://github.com/vidarh/file_writer
75
76
  licenses:
76
77
  - MIT
@@ -90,8 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
91
  - !ruby/object:Gem::Version
91
92
  version: '0'
92
93
  requirements: []
93
- rubyforge_project:
94
- rubygems_version: 2.5.2
94
+ rubygems_version: 3.1.4
95
95
  signing_key:
96
96
  specification_version: 4
97
97
  summary: Overwrite/replace files in a safe way with backups