Class: FakeS3::SortedObjectList

Inherits:
Object
  • Object
show all
Defined in:
lib/fakes3/sorted_object_list.rb

Overview

This class has some of the semantics necessary for how buckets can return their items

It is currently implemented naively as a sorted set + hash If you are going to try to put massive lists inside buckets and ls them, you will be sorely disappointed about this performance.

Instance Method Summary collapse

Constructor Details

#initializeSortedObjectList

Returns a new instance of SortedObjectList.



20
21
22
23
24
# File 'lib/fakes3/sorted_object_list.rb', line 20

def initialize
  @sorted_set = SortedSet.new
  @object_map = {}
  @mutex = Mutex.new
end

Instance Method Details

#add(s3_object) ⇒ Object

Add an S3 object into the sorted list



35
36
37
38
39
40
# File 'lib/fakes3/sorted_object_list.rb', line 35

def add(s3_object)
  return if !s3_object

  @object_map[s3_object.name] = s3_object
  @sorted_set << s3_object
end

#countObject



26
27
28
# File 'lib/fakes3/sorted_object_list.rb', line 26

def count
  @sorted_set.count
end

#find(object_name) ⇒ Object



30
31
32
# File 'lib/fakes3/sorted_object_list.rb', line 30

def find(object_name)
  @object_map[object_name]
end

#list(options) ⇒ Object

Return back a set of matches based on the passed in options

options:

:marker : a string to start the lexographical search (it is not included

in the result)

:max_keys : a maximum number of results :prefix : a string to filter the results by :delimiter : not supported yet



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/fakes3/sorted_object_list.rb', line 58

def list(options)
  marker = options[:marker]
  prefix = options[:prefix]
  max_keys = options[:max_keys] || 1000
  delimiter = options[:delimiter]

  ms = S3MatchSet.new

  marker_found = true
  pseudo = nil
  if marker
    marker_found = false
    if !@object_map[marker]
      pseudo = S3Object.new
      pseudo.name = marker
      @sorted_set << pseudo
    end
  end

  if delimiter
    if prefix
      base_prefix = prefix
    else
      base_prefix = ""
    end
    prefix_offset = base_prefix.length
  end

  count = 0
  last_chunk = nil
  @sorted_set.each do |s3_object|
    if marker_found && (!prefix or s3_object.name.index(prefix) == 0)
      if delimiter
        name = s3_object.name
        remainder = name.slice(prefix_offset, name.length)
        chunks = remainder.split(delimiter, 2)
        if chunks.length > 1
          if (last_chunk != chunks[0])
            # "All of the keys rolled up in a common prefix count as
            # a single return when calculating the number of
            # returns. See MaxKeys."
            # (http://awsdocs.s3.amazonaws.com/S3/latest/s3-api.pdf)
            count += 1
            if count <= max_keys
              ms.common_prefixes << base_prefix + chunks[0] + delimiter
              last_chunk = chunks[0]
            else
              is_truncated = true
              break
            end
          end

          # Continue to the next key, since this one has a
          # delimiter.
          next
        end
      end

      count += 1
      if count <= max_keys
        ms.matches << s3_object
      else
        is_truncated = true
        break
      end
    end

    if marker and marker == s3_object.name
      marker_found = true
    end
  end

  if pseudo
    @sorted_set.delete(pseudo)
  end

  return ms
end

#remove(s3_object) ⇒ Object



42
43
44
45
46
47
# File 'lib/fakes3/sorted_object_list.rb', line 42

def remove(s3_object)
  return if !s3_object

  @object_map.delete(s3_object.name)
  @sorted_set.delete(s3_object)
end