s3fsr 1.7 → 1.8

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.
data/bin/s3fsr CHANGED
@@ -16,7 +16,8 @@ if ENV['AWS_ACCESS_KEY_ID'] == nil or ENV['AWS_SECRET_ACCESS_KEY'] == nil
16
16
  end
17
17
 
18
18
  root = BUCKET != nil ? SBucketDir.new(nil, BUCKET) : SBucketsDir.new
19
- s3fsr = MethodLogger.new(S3fsr.new(root))
19
+ s3fsr = S3fsr.new(root)
20
+ # s3fsr = MethodLogger.new(s3fsr)
20
21
  FuseFS.set_root s3fsr
21
22
  FuseFS.mount_under MOUNT #, "allow_other"
22
23
  begin
@@ -303,6 +303,10 @@ module AWS
303
303
  when :deleted then object_cache.delete(object)
304
304
  end
305
305
  end
306
+
307
+ def truncated?
308
+ attributes['is_truncated']
309
+ end
306
310
 
307
311
  private
308
312
  def build_contents!
data/lib/s3fsr.rb CHANGED
@@ -9,13 +9,25 @@ S3SYNC_DIR_ETAG = 'd66759af42f282e1ba19144df2d405d0'
9
9
  S3SYNC_DIR_LENGTH = 38
10
10
  AWS::S3::Base.establish_connection!(:access_key_id => ENV['AWS_ACCESS_KEY_ID'], :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'])
11
11
 
12
+ # old key split name perf sucked, so optimize with a cached rindex/slice
13
+ def last_part(key)
14
+ last_slash = key.rindex('/', -2)
15
+ drop = key.end_with?('/') ? 1 : 0
16
+ if last_slash then
17
+ key.slice(last_slash + 1, key.length - last_slash - 1 - drop)
18
+ else
19
+ key.slice(0, key.length - drop)
20
+ end
21
+ end
22
+
12
23
  class SFile
13
24
  def initialize(parent, s3obj)
14
25
  @parent = parent
15
26
  @s3obj = s3obj
27
+ @name = last_part(@s3obj.key)
16
28
  end
17
29
  def name
18
- @s3obj.key.split('/')[-1]
30
+ @name
19
31
  end
20
32
  def is_directory?
21
33
  false
@@ -51,25 +63,27 @@ class SBaseDir
51
63
  true
52
64
  end
53
65
  def content_deleted name
54
- get_contents.delete_if { |i| i.name == name }
66
+ get_contents.delete name
55
67
  end
56
68
  def create_file child_key, content
57
69
  AWS::S3::S3Object.store(child_key, content, bucket)
58
- get_contents << SFile.new(self, AWS::S3::S3Object.find(child_key, bucket))
70
+ f = SFile.new(self, AWS::S3::S3Object.find(child_key, bucket))
71
+ get_contents[f.name] = f
59
72
  end
60
73
  def create_dir child_key
61
74
  AWS::S3::S3Object.store(child_key + '/', '', bucket)
62
- get_contents << SPrefixDir.new(self, child_key + '/')
75
+ d = SPrefixDir.new(self, child_key + '/')
76
+ get_contents[d.name] = d
63
77
  end
64
78
  def delete
65
79
  AWS::S3::S3Object.delete @key, bucket
66
80
  @parent.content_deleted name
67
81
  end
68
82
  def contents
69
- get_contents.collect { |i| i.name }
83
+ get_contents.keys
70
84
  end
71
85
  def get(name)
72
- get_contents.find { |i| i.name == name }
86
+ get_contents[name]
73
87
  end
74
88
  def size
75
89
  0
@@ -81,29 +95,41 @@ class SBaseDir
81
95
  def get_contents
82
96
  return @data if @data != nil
83
97
  puts "Loading '#{name}' from #{bucket}..."
84
- @data = []
98
+ @data = {}
85
99
  marker = ''
86
100
  loop do
87
101
  s3_bucket = AWS::S3::Bucket.find(bucket, :prefix => prefix, :delimiter => '/', :marker => marker, :max_keys => 1000)
88
- s3_bucket.object_cache.each do |s3_obj|
102
+
103
+ oc = s3_bucket.object_cache
104
+ cpc = s3_bucket.common_prefix_cache
105
+
106
+ cpc.reject { |p| p == '/' }.each do |prefix|
107
+ d = SPrefixDir.new(self, prefix)
108
+ @data[d.name] = d
109
+ end
110
+
111
+ oc.each do |s3_obj|
89
112
  # Technically we should use S3SYNC_DIR_LENGTH but aws-s3 decides it
90
113
  # needs to issue an HEAD request for every dir for that.
91
114
  if s3_obj.etag == S3SYNC_DIR_ETAG or s3_obj.key.end_with? S3ORGANIZER_DIR_SUFFIX
92
- @data << SFakeDir.new(self, s3_obj.key)
115
+ d = SFakeDir.new(self, s3_obj.key)
116
+ @data[d.name] = d
93
117
  elsif s3_obj.key.end_with? '/'
94
118
  # We passed 'prefix/', delimiter='/', if we get any keys that
95
119
  # end with /, it's just a marker object for our current directory
96
120
  # so ignore it.
97
121
  else
98
- @data << SFile.new(self, s3_obj)
122
+ f = SFile.new(self, s3_obj)
123
+ @data[f.name] = f
99
124
  end
100
125
  end
101
- s3_bucket.common_prefix_cache.reject { |p| p == '/' }.each do |prefix|
102
- hidden = SPrefixDir.new(self, prefix)
103
- @data << hidden unless @data.find { |i| i.name == hidden.name }
104
- end
105
- break unless s3_bucket.object_cache.length > 0 && s3_bucket.object_cache.length % 1000 == 0
106
- marker = s3_bucket.object_cache.last.key
126
+
127
+ break unless s3_bucket.truncated?
128
+
129
+ # find which of the object/prefix keys is alphabetically last
130
+ last_object_key = oc.size == 0 ? '' : oc.last.key
131
+ last_prefix_key = cpc.size == 0 ? '' : cpc.last
132
+ marker = last_object_key < last_prefix_key ? last_prefix_key : last_object_key
107
133
  end
108
134
  puts "done"
109
135
  @data
@@ -116,9 +142,10 @@ class SPrefixDir < SBaseDir
116
142
  @parent = parent
117
143
  @key = key
118
144
  @data = nil
145
+ @name = last_part(@key)
119
146
  end
120
147
  def name
121
- @key.split('/')[-1]
148
+ @name
122
149
  end
123
150
  def bucket
124
151
  @parent.bucket
@@ -135,9 +162,10 @@ class SFakeDir < SBaseDir
135
162
  @parent = parent
136
163
  @key = key
137
164
  @data = nil
165
+ @name = strip_dir_suffix(last_part(@key))
138
166
  end
139
167
  def name
140
- strip_dir_suffix @key.split('/')[-1]
168
+ @name
141
169
  end
142
170
  def bucket
143
171
  @parent.bucket
@@ -188,7 +216,8 @@ class SBucketsDir < SBaseDir
188
216
  end
189
217
  def create_dir child_key
190
218
  AWS::S3::Bucket.create(child_key)
191
- get_contents << SBucketDir.new(self, child_key)
219
+ d = SBucketDir.new(self, child_key)
220
+ get_contents[d.name] = d
192
221
  end
193
222
  def delete
194
223
  raise 'cannot delete the buckets dir'
@@ -205,9 +234,10 @@ class SBucketsDir < SBaseDir
205
234
  def get_contents
206
235
  return @data if @data != nil
207
236
  puts "Loading buckets..."
208
- @data = []
237
+ @data = {}
209
238
  AWS::S3::Bucket.list(true).each do |s3_bucket|
210
- @data << SBucketDir.new(self, s3_bucket.name)
239
+ d = SBucketDir.new(self, s3_bucket.name)
240
+ @data[d.name] = d
211
241
  end
212
242
  puts "done"
213
243
  @data
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: s3fsr
3
3
  version: !ruby/object:Gem::Version
4
- hash: 1
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
- - 7
9
- version: "1.7"
8
+ - 8
9
+ version: "1.8"
10
10
  platform: ruby
11
11
  authors:
12
12
  - Stephen Haberman
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-11-13 00:00:00 -06:00
17
+ date: 2011-01-25 00:00:00 -06:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency