@@ -108,7 +108,7 @@ impl<T> Deque<T> {
108
108
/// Prepend an element to the deque
109
109
pub fn add_front ( & mut self , t : T ) {
110
110
if self . nelts == self . elts . len ( ) {
111
- grow ( self . nelts , self . lo , & mut self . elts ) ;
111
+ grow ( self . nelts , & mut self . lo , & mut self . elts ) ;
112
112
}
113
113
if self . lo == 0 u {
114
114
self . lo = self . elts . len ( ) - 1 u;
@@ -120,7 +120,7 @@ impl<T> Deque<T> {
120
120
/// Append an element to the deque
121
121
pub fn add_back ( & mut self , t : T ) {
122
122
if self . nelts == self . elts . len ( ) {
123
- grow ( self . nelts , self . lo , & mut self . elts ) ;
123
+ grow ( self . nelts , & mut self . lo , & mut self . elts ) ;
124
124
}
125
125
let hi = self . raw_index ( self . nelts ) ;
126
126
self . elts [ hi] = Some ( t) ;
@@ -230,18 +230,36 @@ iterator!{impl DequeMutRevIterator -> &'self mut T, get_mut_ref, -1}
230
230
231
231
/// Grow is only called on full elts, so nelts is also len(elts), unlike
232
232
/// elsewhere.
233
- fn grow < T > ( nelts : uint , lo : uint , elts : & mut ~[ Option < T > ] ) {
233
+ fn grow < T > ( nelts : uint , loptr : & mut uint , elts : & mut ~[ Option < T > ] ) {
234
234
assert_eq ! ( nelts, elts. len( ) ) ;
235
- let newlen = elts. capacity ( ) * 2 ;
235
+ let lo = * loptr;
236
+ let newlen = nelts * 2 ;
236
237
elts. reserve ( newlen) ;
237
238
238
239
/* fill with None */
239
240
for uint:: range( elts. len( ) , elts. capacity( ) ) |_| {
240
241
elts. push ( None ) ;
241
242
}
242
- /* move the former wraparound to the new half */
243
- for uint:: range( 0 , lo) |i| {
244
- elts. swap ( i, nelts + i) ;
243
+
244
+ /*
245
+ Move the shortest half into the newly reserved area.
246
+ lo ---->|
247
+ nelts ----------->|
248
+ [o o o|o o o o o]
249
+ A [. . .|o o o o o o o o|. . . . .]
250
+ B [o o o|. . . . . . . .|o o o o o]
251
+ */
252
+
253
+ assert ! ( newlen - nelts/2 >= nelts) ;
254
+ if lo <= ( nelts - lo) { // A
255
+ for uint:: range( 0 , lo) |i| {
256
+ elts. swap ( i, nelts + i) ;
257
+ }
258
+ } else { // B
259
+ for uint:: range( lo, nelts) |i| {
260
+ elts. swap ( i, newlen - nelts + i) ;
261
+ }
262
+ * loptr += newlen - nelts;
245
263
}
246
264
}
247
265
0 commit comments