Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: third_party/gsutil/boto/sdb/db/sequence.py

Issue 12042069: Scripts to download files from google storage based on sha1 sums (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Removed gsutil/tests and gsutil/docs Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright (c) 2010 Chris Moyer http://coredumped.org/
2 #
3 # Permission is hereby granted, free of charge, to any person obtaining a
4 # copy of this software and associated documentation files (the
5 # "Software"), to deal in the Software without restriction, including
6 # without limitation the rights to use, copy, modify, merge, publish, dis-
7 # tribute, sublicense, and/or sell copies of the Software, and to permit
8 # persons to whom the Software is furnished to do so, subject to the fol-
9 # lowing conditions:
10 #
11 # The above copyright notice and this permission notice shall be included
12 # in all copies or substantial portions of the Software.
13 #
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 # IN THE SOFTWARE.
21
22 from boto.exception import SDBResponseError
23
24 class SequenceGenerator(object):
25 """Generic Sequence Generator object, this takes a single
26 string as the "sequence" and uses that to figure out
27 what the next value in a string is. For example
28 if you give "ABC" and pass in "A" it will give you "B",
29 and if you give it "C" it will give you "AA".
30
31 If you set "rollover" to True in the above example, passing
32 in "C" would give you "A" again.
33
34 The Sequence string can be a string or any iterable
35 that has the "index" function and is indexable.
36 """
37 __name__ = "SequenceGenerator"
38
39 def __init__(self, sequence_string, rollover=False):
40 """Create a new SequenceGenerator using the sequence_string
41 as how to generate the next item.
42
43 :param sequence_string: The string or list that explains
44 how to generate the next item in the sequence
45 :type sequence_string: str,iterable
46
47 :param rollover: Rollover instead of incrementing when
48 we hit the end of the sequence
49 :type rollover: bool
50 """
51 self.sequence_string = sequence_string
52 self.sequence_length = len(sequence_string[0])
53 self.rollover = rollover
54 self.last_item = sequence_string[-1]
55 self.__name__ = "%s('%s')" % (self.__class__.__name__, sequence_string)
56
57 def __call__(self, val, last=None):
58 """Get the next value in the sequence"""
59 # If they pass us in a string that's not at least
60 # the lenght of our sequence, then return the
61 # first element in our sequence
62 if val == None or len(val) < self.sequence_length:
63 return self.sequence_string[0]
64 last_value = val[-self.sequence_length:]
65 if (not self.rollover) and (last_value == self.last_item):
66 val = "%s%s" % (self(val[:-self.sequence_length]), self._inc(last_va lue))
67 else:
68 val = "%s%s" % (val[:-self.sequence_length], self._inc(last_value))
69 return val
70
71 def _inc(self, val):
72 """Increment a single value"""
73 assert(len(val) == self.sequence_length)
74 return self.sequence_string[(self.sequence_string.index(val)+1) % len(se lf.sequence_string)]
75
76
77
78 #
79 # Simple Sequence Functions
80 #
81 def increment_by_one(cv=None, lv=None):
82 if cv == None:
83 return 0
84 return cv + 1
85
86 def double(cv=None, lv=None):
87 if cv == None:
88 return 1
89 return cv * 2
90
91 def fib(cv=1, lv=0):
92 """The fibonacci sequence, this incrementer uses the
93 last value"""
94 if cv == None:
95 cv = 1
96 if lv == None:
97 lv = 0
98 return cv + lv
99
100 increment_string = SequenceGenerator("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
101
102
103
104 class Sequence(object):
105 """A simple Sequence using the new SDB "Consistent" features
106 Based largly off of the "Counter" example from mitch garnaat:
107 http://bitbucket.org/mitch/stupidbototricks/src/tip/counter.py"""
108
109
110 def __init__(self, id=None, domain_name=None, fnc=increment_by_one, init_val =None):
111 """Create a new Sequence, using an optional function to
112 increment to the next number, by default we just increment by one.
113 Every parameter here is optional, if you don't specify any options
114 then you'll get a new SequenceGenerator with a random ID stored in the
115 default domain that increments by one and uses the default botoweb
116 environment
117
118 :param id: Optional ID (name) for this counter
119 :type id: str
120
121 :param domain_name: Optional domain name to use, by default we get this out of the
122 environment configuration
123 :type domain_name:str
124
125 :param fnc: Optional function to use for the incrementation, by default we just increment by one
126 There are several functions defined in this module.
127 Your function must accept "None" to get the initial value
128 :type fnc: function, str
129
130 :param init_val: Initial value, by default this is the first element in your sequence,
131 but you can pass in any value, even a string if you pass in a functi on that uses
132 strings instead of ints to increment
133 """
134 self._db = None
135 self._value = None
136 self.last_value = None
137 self.domain_name = domain_name
138 self.id = id
139 if init_val == None:
140 init_val = fnc(init_val)
141
142 if self.id == None:
143 import uuid
144 self.id = str(uuid.uuid4())
145
146 self.item_type = type(fnc(None))
147 self.timestamp = None
148 # Allow us to pass in a full name to a function
149 if isinstance(fnc, str):
150 from boto.utils import find_class
151 fnc = find_class(fnc)
152 self.fnc = fnc
153
154 # Bootstrap the value last
155 if not self.val:
156 self.val = init_val
157
158 def set(self, val):
159 """Set the value"""
160 import time
161 now = time.time()
162 expected_value = []
163 new_val = {}
164 new_val['timestamp'] = now
165 if self._value != None:
166 new_val['last_value'] = self._value
167 expected_value = ['current_value', str(self._value)]
168 new_val['current_value'] = val
169 try:
170 self.db.put_attributes(self.id, new_val, expected_value=expected_val ue)
171 self.timestamp = new_val['timestamp']
172 except SDBResponseError, e:
173 if e.status == 409:
174 raise ValueError("Sequence out of sync")
175 else:
176 raise
177
178
179 def get(self):
180 """Get the value"""
181 val = self.db.get_attributes(self.id, consistent_read=True)
182 if val:
183 if 'timestamp' in val:
184 self.timestamp = val['timestamp']
185 if 'current_value' in val:
186 self._value = self.item_type(val['current_value'])
187 if "last_value" in val and val['last_value'] != None:
188 self.last_value = self.item_type(val['last_value'])
189 return self._value
190
191 val = property(get, set)
192
193 def __repr__(self):
194 return "%s('%s', '%s', '%s.%s', '%s')" % (
195 self.__class__.__name__,
196 self.id,
197 self.domain_name,
198 self.fnc.__module__, self.fnc.__name__,
199 self.val)
200
201
202 def _connect(self):
203 """Connect to our domain"""
204 if not self._db:
205 import boto
206 sdb = boto.connect_sdb()
207 if not self.domain_name:
208 self.domain_name = boto.config.get("DB", "sequence_db", boto.con fig.get("DB", "db_name", "default"))
209 try:
210 self._db = sdb.get_domain(self.domain_name)
211 except SDBResponseError, e:
212 if e.status == 400:
213 self._db = sdb.create_domain(self.domain_name)
214 else:
215 raise
216 return self._db
217
218 db = property(_connect)
219
220 def next(self):
221 self.val = self.fnc(self.val, self.last_value)
222 return self.val
223
224 def delete(self):
225 """Remove this sequence"""
226 self.db.delete_attributes(self.id)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698