Ticket #4887: location.patch

File location.patch, 26.9 KB (added by ross, 3 years ago)

patch

Line 
11 patch for repository darcs.haskell.org:/srv/darcs/packages/containers:
2
3Fri Jan  7 17:12:08 GMT 2011  Ross Paterson <ross@soi.city.ac.uk>
4  * add a Location interface for element-wise operations
5 
6  This is a variant of a suggestion by apfelmus:
7 
8  http://www.haskell.org/pipermail/libraries/2010-September/014510.html
9 
10  To avoid proliferation of variants of element-wise operations, the idea
11  is to split these operations into two phases mediated by a new Location
12  type, so that users can do whatever they like between these phases.
13
14New patches:
15
16[add a Location interface for element-wise operations
17Ross Paterson <ross@soi.city.ac.uk>**20110107171208
18 Ignore-this: eae16f6e0219241daf0b1d6dbc9662a1
19 
20 This is a variant of a suggestion by apfelmus:
21 
22 http://www.haskell.org/pipermail/libraries/2010-September/014510.html
23 
24 To avoid proliferation of variants of element-wise operations, the idea
25 is to split these operations into two phases mediated by a new Location
26 type, so that users can do whatever they like between these phases.
27] {
28hunk ./Data/Map.hs 65
29             -- * Operators
30             , (!), (\\)
31 
32+            -- * Locations
33+            , Location
34+            -- ** Components
35+            , key
36+            , before
37+            , after
38+            -- ** Locations in maps
39+            , search
40+            , index
41+            , minLocation
42+            , maxLocation
43+            -- ** Building maps
44+            , assign
45+            , clear
46+
47             -- * Query
48             , null
49             , size
50hunk ./Data/Map.hs 305
51 
52 #endif
53 
54+{--------------------------------------------------------------------
55+  Map locations
56+--------------------------------------------------------------------}
57+
58+-- | A location represents a map with a \"hole\" at a particular key
59+-- position.
60+--
61+-- Locations are used for element-wise operations on maps (insertion,
62+-- deletion and update) in a two-stage process:
63+--
64+-- (1) A 'Location' (and the value at that position, if any) is obtained
65+--     from a 'Map' by searching or indexing.
66+--
67+-- (2) A new 'Map' is made from a 'Location' by either filling the hole
68+--     with a value ('assign') or erasing it ('clear').
69+
70+data Location k a
71+    = Empty !k !(Path k a)
72+    | Full {-# UNPACK #-} !Size !k !(Path k a) !(Map k a) !(Map k a)
73+
74+data Path k a
75+    = Root
76+    | LeftBin {-# UNPACK #-} !Size !k a !(Path k a) !(Map k a)
77+    | RightBin {-# UNPACK #-} !Size !k a !(Map k a) !(Path k a)
78+
79+-- | /O(log n)/. Search the map for the given key, returning the
80+-- corresponding value (if any) and an updatable location for that key.
81+--
82+-- Properties:
83+--
84+-- @
85+-- case 'search' k m of
86+--     (Nothing, loc) -> 'key' loc == k && 'clear' loc == m
87+--     (Just v,  loc) -> 'key' loc == k && 'assign' v loc == m
88+-- @
89+--
90+-- @'lookup' k m == 'fst' ('search' k m)@
91+
92+search :: Ord k => k -> Map k a -> (Maybe a, Location k a)
93+search k = k `seq` go Root
94+  where
95+    go path Tip = (Nothing, Empty k path)
96+    go path (Bin sx kx x l r) = case compare k kx of
97+       LT -> go (LeftBin sx kx x path r) l
98+       GT -> go (RightBin sx kx x l path) r
99+       EQ -> (Just x, Full sx kx path l r)
100+
101+-- | /O(log n)/. Return the value and an updatable location for the
102+-- /i/th key in the map.  Calls 'error' if /i/ is out of range.
103+--
104+-- Properties:
105+--
106+-- @
107+-- 0 \<= i && i \< 'size' m ==>
108+--     let (v, loc) = 'index' i m in
109+--         'size' ('before' loc) == i && 'assign' v loc == m
110+-- @
111+--
112+-- @'elemAt' i m == let (v, loc) = 'index' i m in ('key' loc, v)@
113+
114+index :: Int -> Map k a -> (a, Location k a)
115+index = go Root
116+  where
117+    STRICT_2_OF_3(go)
118+    go _path _i Tip = error "Map.index: out of range"
119+    go path i (Bin sx kx x l r) = case compare i size_l of
120+        LT -> go (LeftBin sx kx x path r) i l
121+        GT -> go (RightBin sx kx x l path) (i-size_l-1) r
122+        EQ -> (x, Full sx kx path l r)
123+      where size_l = size l
124+
125+-- | /O(log n)/. Return the value and an updatable location for the
126+-- least key in the map, which must be non-empty.
127+--
128+-- Properties:
129+--
130+-- @
131+-- 'size' m > 0 ==>
132+--     let (v, loc) = 'minLocation' i m in
133+--         'size' (`before` loc) == 0 && 'assign' v loc == m
134+-- @
135+--
136+-- @'findMin' m == let (v, loc) = 'minLocation' i m in ('key' loc, v)@
137+
138+minLocation :: Map k a -> (a, Location k a)
139+minLocation = go Root
140+  where
141+    go _path Tip = error "Map.least: empty map"
142+    go path (Bin sx kx x Tip r) = (x, Full sx kx path Tip r)
143+    go path (Bin sx kx x l r) = go (LeftBin sx kx x path r) l
144+
145+-- | /O(log n)/. Return the value and an updatable location for the
146+-- greatest key in the map, which must be non-empty.
147+--
148+-- Properties:
149+--
150+-- @
151+-- 'size' m > 0 ==>
152+--     let (v, loc) = 'maxLocation' i m in
153+--         'size' (`after` loc) == 0 && 'assign' v loc == m
154+-- @
155+--
156+-- @'findMax' m == let (v, loc) = 'maxLocation' i m in ('key' loc, v)@
157+
158+maxLocation :: Map k a -> (a, Location k a)
159+maxLocation = go Root
160+  where
161+    go _path Tip = error "Map.greatest: empty map"
162+    go path (Bin sx kx x l Tip) = (x, Full sx kx path l Tip)
163+    go path (Bin sx kx x l r) = go (RightBin sx kx x l path) r
164+
165+-- | /O(1)/. The key marking the position of the \"hole\" in the map.
166+key :: Location k a -> k
167+key (Empty k _path) = k
168+key (Full _sx kx _path _l _r) = kx
169+
170+-- | /O(log n)/. @'before' loc@ is the submap with keys less than @'key' loc@.
171+before :: Ord k => Location k a -> Map k a
172+before (Empty _k path) = buildBefore Tip path
173+before (Full _sx _kx path l _r) = buildBefore l path
174+
175+buildBefore :: Ord k => Map k a -> Path k a -> Map k a
176+buildBefore t Root = t
177+buildBefore t (LeftBin _sx _kx _x path _r) = buildBefore t path
178+buildBefore t (RightBin _sx kx x l path) = buildBefore (join kx x l t) path
179+
180+-- | /O(log n)/. @'after' loc@ is the submap with keys greater than @'key' loc@.
181+after :: Ord k => Location k a -> Map k a
182+after (Empty _k path) = buildAfter Tip path
183+after (Full _sx _kx path l _r) = buildAfter l path
184+
185+buildAfter :: Ord k => Map k a -> Path k a -> Map k a
186+buildAfter t Root = t
187+buildAfter t (LeftBin _sx kx x path r) = buildAfter (join kx x t r) path
188+buildAfter t (RightBin _sx _kx _x _l path) = buildAfter t path
189+
190+-- | /O(log n)/. Return a map obtained by placing the given value
191+-- at the location (replacing an existing value, if any).
192+--
193+-- @'assign' v loc == 'before' loc `union` 'singleton' ('key' loc) v `union` 'after' loc@
194+
195+assign :: a -> Location k a -> Map k a
196+assign x (Empty k path) = rebuildGT (singleton k x) path
197+assign x (Full sx kx path l r) = rebuildEQ (Bin sx kx x l r) path
198+
199+-- | /O(log n)/. Return a map obtained by erasing the location.
200+--
201+-- @'clear' loc == 'before' loc `union` 'after' loc@
202+
203+clear :: Location k a -> Map k a
204+clear (Empty _k path) = rebuildEQ Tip path
205+clear (Full _sx _kx path l r) = rebuildLT (glue l r) path
206+
207+-- Rebuild the tree the same size as it was, so no rebalancing is needed.
208+rebuildEQ :: Map k a -> Path k a -> Map k a
209+rebuildEQ t Root = t
210+rebuildEQ l (LeftBin sx kx x path r) = rebuildEQ (Bin sx kx x l r) path
211+rebuildEQ r (RightBin sx kx x l path) = rebuildEQ (Bin sx kx x l r) path
212+
213+-- Rebuild the tree one entry smaller than it was, rebalancing as we go.
214+rebuildLT :: Map k a -> Path k a -> Map k a
215+rebuildLT t Root = t
216+rebuildLT l (LeftBin _sx kx x path r) = rebuildLT (balanceR kx x l r) path
217+rebuildLT r (RightBin _sx kx x l path) = rebuildLT (balanceL kx x l r) path
218+
219+-- Rebuild the tree one entry larger than it was, rebalancing as we go.
220+rebuildGT :: Map k a -> Path k a -> Map k a
221+rebuildGT t Root = t
222+rebuildGT l (LeftBin _sx kx x path r) = rebuildGT (balanceL kx x l r) path
223+rebuildGT r (RightBin _sx kx x l path) = rebuildGT (balanceR kx x l r) path
224+
225 {--------------------------------------------------------------------
226   Query
227 --------------------------------------------------------------------}
228}
229
230Context:
231
232[hoist constant parameter
233Ross Paterson <ross@soi.city.ac.uk>**20110107155012
234 Ignore-this: 1061fdf82eb91cad409ccea022610856
235]
236[fix typos in comments
237Ross Paterson <ross@soi.city.ac.uk>**20101215172553
238 Ignore-this: f66f871ce348a41bc1598bc2b5e40943
239]
240[whitespace changes and a little re-ordering to make the export lists match
241Ross Paterson <ross@soi.city.ac.uk>**20101215170649
242 Ignore-this: 3bf7b6d824ea1c25ed92bbe3ca826efe
243]
244[whitespace changes and a little re-ordering to make the export lists match
245Ross Paterson <ross@soi.city.ac.uk>**20101215162127
246 Ignore-this: 7f11aef6c6c8330bb93b6571589e18af
247]
248[change Int to Key (type synonym) in 3 places for consistency
249Ross Paterson <ross@soi.city.ac.uk>**20101215150459
250 Ignore-this: 6da6f8629bb0718e2394a85ce0944d7f
251]
252[use Applicative form in Arbitrary instances
253Ross Paterson <ross@soi.city.ac.uk>**20101213040129
254 Ignore-this: 335e6eac24563baef481fdc689f369dc
255 (these are ifdef'ed out by default)
256]
257[fix comment for unfoldl
258Ross Paterson <ross@soi.city.ac.uk>**20101213040022
259 Ignore-this: c4bac18538933b981ed2875595f98196
260]
261[make local binding monomorphic without using scoped type variables
262Ross Paterson <ross@soi.city.ac.uk>**20101213035831
263 Ignore-this: 52b7f5ed7cb7c6ef0eda6caa39e4713f
264]
265[Always inline foldrWithKey' and foldlWithKey' from Data.Map
266Johan Tibell <johan.tibell@gmail.com>**20101201110527
267 Ignore-this: a84198febd304659ff029c3424855be3
268 
269 Inlining makes it possible to replace an indirect call to an unknown
270 function with a call to a known function at the call site.
271]
272[Tweak insertWith' and insertWithKey' to better match the non-' versions
273Ian Lynagh <igloo@earth.li>**20101128175028
274 Ignore-this: 41b50b13b1a94ae56bad8d381c696d04
275 They now are not marked inlinable, force the key, and are exported.
276]
277[Add foldlWithKey' and foldrWithKey' to Data.Map
278Johan Tibell <johan.tibell@gmail.com>**20101103132836
279 Ignore-this: d2ac0f0a50842ec5a007b9ad11ce63d0
280]
281[Add strict versions of insertWith and insertWithKey to IntMap
282Johan Tibell <johan.tibell@gmail.com>**20101030135122
283 Ignore-this: 5472c9be565e75672140d243ef0211f2
284]
285[Explain INLINEs in IntMap and IntSet.
286Milan Straka <fox@ucw.cz>**20101104224507
287 Ignore-this: 322a22056e9aa5d4e5a9f2caa6542017
288]
289[Fix warnings.
290Milan Straka <fox@ucw.cz>**20101104223950
291 Ignore-this: 19460b7cab4554fef3b637ebb36addd1
292 
293 Just trivial renames of shadows variables.
294]
295[Explain the nomatch clause in IntSet.hs
296Milan Straka <fox@ucw.cz>**20101104221451
297 Ignore-this: 2f90d0037027e77cffff30cf21729845
298]
299[Rename STRICTxy to STRICT_x_OF_y.
300Milan Straka <fox@ucw.cz>**20101104220917
301 Ignore-this: fb12cee5518d1a8844ee44273330fa57
302 
303 Also explain why bang patterns are not used.
304]
305[Settle performance issues in Map and Set.
306Milan Straka <fox@ucw.cz>**20101031082146
307 Ignore-this: 9a4c70d5f9a5884c7ff8f714ae4ff1e4
308 
309 Explain the INLINE/INLINABLE in the Map and Set sources.
310 
311 Use 'go' only for functions that can be INLINE.
312]
313[Settle performance issues in IntMap and IntSet.
314Milan Straka <fox@ucw.cz>**20101029231653
315 Ignore-this: c1234a5113da14178a2394976e91b786
316 
317 The worker-wrapper transformation is removed from
318 all functions but lookup and member. This is the
319 only place where it causes benefits -- a 10% to
320 15% speedup. It increases memory allocation
321 slightly (0-5%), but the effect on GHC is really
322 minor.
323 
324 Also INLINE/INLINABLE hints are not really needed,
325 GHC figures it all by itself. The explicit INLINE
326 were left on internal functions that are crutial
327 to INLINE because of performance.
328]
329[Make foldlStrict semantics to match foldl'.
330Milan Straka <fox@ucw.cz>**20101022100939
331 Ignore-this: 3790a5a47e4ff7b55c005a8c95e5890f
332]
333[Remove INLINABLE in IntMap and IntSet.hs.
334Milan Straka <fox@ucw.cz>**20101022091744
335 Ignore-this: 4f532887bf54444989cc66d6546f1c89
336 
337 It makes no sense, as the calls are already specialized
338 for Int keys. Benchmarks actually show small slowdown.
339]
340[Do not pass f explicitely for fold.
341Milan Straka <fox@ucw.cz>**20101019202043
342 Ignore-this: bb0a5e758ebfebbdf8160be4317898e9
343 
344 Benchmarks shows this is a huge win (100% for (:) being
345 the function, 1000% for (+) being the function).
346]
347[Mark fold explicitely as INLINE.
348Milan Straka <fox@ucw.cz>**20101016222150
349 Ignore-this: b72855a0af39e57b1862908717fc14fc
350 
351 The INLINABLE does not work well in this case. Benchmarks
352 show memory savings (due to unboxing) and nearly no GHC binary
353 size increase.
354]
355[Changing INLINE pragmas.
356Milan Straka <fox@ucw.cz>**20101016215959
357 Ignore-this: 933327354749d18e4617280fde55cce0
358 
359 The internal functions that need to be inlined are marked INLINE
360 (bit fiddling in IntMap/IntSet, empty, singleton, bin).
361 
362 Aslo if INLINABLE is available, use it for all exported functions.
363 The functions like insert that were INLINE because of specialization
364 issues are now INLINE only in the case of INLINABLE absence.
365]
366[Whitespace changes only.
367Milan Straka <fox@ucw.cz>**20101016202831
368 Ignore-this: 8850e09fb49937b54da6585d01aade9a
369]
370[Correct a typo in macro name.
371Milan Straka <fox@ucw.cz>**20101016202641
372 Ignore-this: 356621b0ca954f73d543fc33d43383b2
373]
374[Change the worker/wrapper to explicitly pass arguments.
375Milan Straka <fox@ucw.cz>**20101016195757
376 Ignore-this: 7f4a2180a263ee15cbb73c60b2d8cc46
377 
378 As the benchmarking showed, it is not a good idea to create
379 closures in the worker/wrapper transformation, as the captured
380 arguments of the enclosing function have to be allocated on the
381 heap. It is better to explicitly pass the arguments on the stack.
382 This saves memory and add no time penalty if the arguments are
383 the first arguments of recursive function (GHC refrains from
384 needless copying).
385 
386 The worker is often strict in some arguments. I did not want
387 to use BangPatterns, so I used macros to indicate strictness.
388 If majority thinks BangPatters are fine, I will gladly change it.
389]
390[Fix warnings in Data.Map and Data.Set.
391Milan Straka <fox@ucw.cz>**20100924154946
392 Ignore-this: cb2c0a8ecf0a57acc5941ba841aa7c40
393 
394 Only trivial changes.
395]
396[Finish the started worker/wrapper transformation.
397Milan Straka <fox@ucw.cz>**20100924153353
398 Ignore-this: baeb24573242beb56c3bbe7ca67f5ff7
399 
400 Some methods (insert, lookup) were not modified as the rest
401 (like insertWith, delete, ...). Also the `seq` were missing
402 sometimes.
403]
404[Merge all the OPTIONS and LANGUAGE module pragmas.
405Milan Straka <fox@ucw.cz>**20100924152642
406 Ignore-this: 86067abf13f0501f29c13ec7c877533c
407]
408[Remove most INLINE from Map, Set, IntMap and IntSet.
409Milan Straka <fox@ucw.cz>**20100924152008
410 Ignore-this: c88c4ede21c06bfda20af131c232a720
411 
412 Because of a code bloat the INLINEs cause, remove most of
413 them. The only INLINEs left are the following:
414 - only in Set and Map, because in IntMap and IntSet the specialization
415   does not help
416 - only on functions which need Ord
417 - only on 'small' functions, namely member, notMember, lookup*,
418   insert*, delete*, adjust*, alter*, update*
419 
420 All other functions of Map, Set, IntMap and IntSet are marked INLINABLE,
421 even if they are recursive.
422 
423 The INLINEs left are only a short-term solution. In the long run the
424 auto-specialization of INLINABLE methods seems a good way (maybe
425 SPECIALIZABLE).
426]
427[Comment tests and benchmarks on foldlWithKey' which
428Milan Straka <fox@ucw.cz>**20100924110705
429 Ignore-this: 71b988389e6ae9a78ea3b0e20156ca2f
430 was commented recently by Ian Lynagh.
431]
432[Worker/wrapper transformation for Data.IntSet.
433Milan Straka <fox@ucw.cz>**20100923125604
434 Ignore-this: b0228582818f7bfb690d0853022a7809
435]
436[Compile only the benchmark source, not the Data/*.hs.
437Milan Straka <fox@ucw.cz>**20100921115821
438 Ignore-this: f94d9e3ffe126cd057d23490c973a4e9
439]
440[Add criterion-based benchmark for IntSet.hs.
441Milan Straka <fox@ucw.cz>**20100921103225
442 Ignore-this: 3d31a820830c7382748626bc9a1ba54
443 
444 The benchmark is nearly identical copy of Set.hs benchmark.
445]
446[Add a testsuite for Data.IntSet.
447Milan Straka <fox@ucw.cz>**20100921102802
448 Ignore-this: e55484ee185e71915452bdf2a7b2a2b3
449]
450[Further improve Data.Set balance function.
451Milan Straka <fox@ucw.cz>**20100921091828
452 Ignore-this: f23be37859224e9bbe919a3c0a71fdc6
453 
454 As suggested by Kazu Yamamoto, we split balance to balanceL and
455 balanceR, which handle only one-sided inbalance, but need fewer
456 tests than balance.
457 
458 As nearly all functions modifying the structure use balance, this
459 results in speedup of many functions. On my 32-bit GHC 6.12.1,
460 11% speedup for insert, 12% speedup for delete.
461]
462[Further improve Data.Map balance function.
463Milan Straka <fox@ucw.cz>**20100921091547
464 Ignore-this: 8abfd027142a5183b2b5282e96ccb414
465 
466 As suggested by Kazu Yamamoto, we split balance to balanceL and
467 balanceR, which handle only one-sided inbalance, but need fewer
468 tests than balance.
469 
470 As nearly all functions modifying the structure use balance, this
471 results in speedup of many functions. On my 32-bit GHC 6.12.1,
472 20% speedup for insert, 7% speedup for delete, 5% speedup for update.
473]
474[Changing delta to 3 in Data.Set.
475Milan Straka <fox@ucw.cz>**20100921090507
476 Ignore-this: a47d0c542ed9cee99ad6b17c52c977a1
477 
478 Only possible values are 3 and 4. The value 3 has much faster inserts,
479 value 4 slightly faster deletes, so choosing 3.
480 
481 Also changed the inequalities to rebalance only when one subtree
482 is _strictly_ larger than delta * the other one, to mimic the behaviour
483 from the proof (both from the Adams' and from the one to come).
484]
485[Changing delta to 3 in Data.Map.
486Milan Straka <fox@ucw.cz>**20100921090358
487 Ignore-this: 85f733f836b65b2b1038383ddb92e8e1
488 
489 Only possible values are 3 and 4. The value 3 has much faster inserts,
490 value 4 slightly faster deletes, so choosing 3.
491 
492 Also changed the inequalities to rebalance only when one subtree
493 is _strictly_ larger than delta * the other one, to mimic the behaviour
494 from the proof (both from the Adams' and from the one to come).
495]
496[Correct Data.Set Arbitrary instance never to return unbalanced trees.
497Milan Straka <fox@ucw.cz>**20100914150442
498 Ignore-this: b5c70fa98a56f225b8eb5faf420677b0
499 
500 The previous instance sometimes returned unbalanced trees,
501 which broke the tests.
502 
503 Also the new instance mimics Data.Map instance more closely in the shape
504 of the generated trees.
505]
506[Correct Data.Map Arbitrary instance never to return unbalanced trees.
507Milan Straka <fox@ucw.cz>**20100914145841
508 Ignore-this: 114bbcc63acdb16b77140ea56aeb0a95
509 
510 The previous instance sometimes returned unbalanced trees,
511 which broke the tests.
512]
513[Improve Data.Set benchmark.
514Milan Straka <fox@ucw.cz>**20100914142010
515 Ignore-this: 9b878ae3aa5a43ef083abfd7f9b22513
516 
517 Add union, difference and intersection to Data.Set benchmark.
518]
519[Improve benchmark infrastructure and Data.Map benchmark.
520Milan Straka <fox@ucw.cz>**20100914141707
521 Ignore-this: 67e8dafcb4abcb9c726b9b29c7c320fd
522 
523 Renamed Benchmarks.hs to Map.hs, as it only benchmarks Data.Map.
524 Improve the Makefile to work with multiple benchmarks.
525 Add union, difference and intersection to Data.Map benchmark.
526]
527[Improve the performance of Data.Set balance function.
528Milan Straka <fox@ucw.cz>**20100914140417
529 Ignore-this: 577c511c219695b8d483af546c7387e8
530 
531 The balance function is now one monolithic function, which allows
532 to perform all pattern-matches only once.
533 
534 Nearly all functions modifying Data.Map use balance.
535 The improvements are 12% for insert, 14% for delete (GHC 6.12.1).
536]
537[Improve the performance of Data.Map balance function.
538Milan Straka <fox@ucw.cz>**20100914140217
539 Ignore-this: 951181e035fcac90674dff3300350a1
540 
541 The balance function is now one monolithic function, which allows
542 to perform all pattern-matches only once.
543 
544 Nearly all functions modifying Data.Map use balance.
545 The improvements are 7-11% for various insert*, delete*, alter,
546 update or intersection functions (GHC 6.12.1).
547]
548[Improve performance of Data.Set union and difference operations.
549Milan Straka <fox@ucw.cz>**20100914135725
550 Ignore-this: 6dc4a186ea060b9cdb9e783db71ca280
551 
552 Use datatype storing evaluated bound instead of high-order functions.
553 The improvements are over 25% for both union and difference (GHC 6.12.1).
554]
555[Improve performance of Data.Map union* and difference* operations.
556Milan Straka <fox@ucw.cz>**20100914134614
557 Ignore-this: 35b23a40ef33e9fa14eb81fdee4b152d
558 
559 Use datatype storing evaluated bound instead of high-order functions.
560 The improvements are 22% for union and 20% for difference (GHC 6.12.1).
561]
562[Make the Set store the elements evaluated (bang added).
563Milan Straka <fox@ucw.cz>**20100913165132
564 Ignore-this: b3f230db5bf30d93d3fddf2c81c5f3b4
565]
566[Improved performance of Data.Set
567Johan Tibell <johan.tibell@gmail.com>**20100831124352
568 Ignore-this: 38a304a0408d29a2956aa9a1fc0ce755
569 
570 Performance improvements are due to manually applying the
571 worker/wrapper transformation and strictifying the keys.
572 
573 Average speed-up is 32% on a 2GHz Core 2 Duo on OS X 10.5.8
574]
575[Added benchmarks for Data.Set
576Johan Tibell <johan.tibell@gmail.com>**20100831124225
577 Ignore-this: fcacf88761034b8c534d936f0b336cc0
578]
579[Added a test suite for Data.Set
580Johan Tibell <johan.tibell@gmail.com>**20100831124030
581 Ignore-this: f430dc302c0fcb8b5d62db2272a1d6f7
582 
583 Expression coverage: 74%
584]
585[Remove use of lambdas with irrefutable patterns
586simonpj@microsoft.com**20100923120838
587 Ignore-this: c36e90a0258c0d5262684c585c321419
588]
589[Revert the recent contentious changes
590Ian Lynagh <igloo@earth.li>**20100915135103
591 Ignore-this: fe4f71ff1ade51c11421dc9974aa0fda
592 These will probably be tidied up and reinstated later, but this gets
593 the package back to a releasable state.
594]
595[fix warnings
596Simon Marlow <marlowsd@gmail.com>**20100831114555
597 Ignore-this: 53df71bc054a779b8ad2dad89c09e02d
598]
599[Missing MagicHash for IntSet
600Don Stewart <dons@galois.com>**20100831093446
601 Ignore-this: d075f760adb9a2aa0ee04676e38a07cc
602]
603[Performance improvements for Data.IntMap (worker/wrapper and inlining)
604Don Stewart <dons@galois.com>**20100831093316
605 Ignore-this: 206036448558d270f0eb85ef4cd55368
606]
607[Add criterion-based benchmarking for IntMap
608Don Stewart <dons@galois.com>**20100831093240
609 Ignore-this: d7d85b9afb513532cc30f5b51a3f825e
610]
611[Add comprehensive testsuite for IntMap
612Don Stewart <dons@galois.com>**20100831093202
613 Ignore-this: d455fedbc615e5b63ac488e605550557
614]
615[-O2 -fregs-graph is a uniform 10% improvements for IntMap
616Don Stewart <dons@galois.com>**20100831092956
617 Ignore-this: 2372cf4be945fe7939d0af94e32c567f
618]
619[Missed base case for updateAt worker. Spotted by Jan-Willem Maessen
620Don Stewart <dons@galois.com>**20100829163329
621 Ignore-this: b8daf1c55c163c16f50c3b54cca2dba1
622]
623[Major bump (new functions, clarified strictness properties, vastly better performance)
624Don Stewart <dons@galois.com>**20100829122628
625 Ignore-this: 9bfbc58ecaa24a86be37b8c4cb043457
626]
627[Add two new functions: foldlWithKey' and insertLookupWithKey'
628Don Stewart <dons@galois.com>**20100829122147
629 Ignore-this: a2f112653ba38737fe1b38609e06c314
630 
631 These two functions use strict accumulators, compared to their existing
632 counterparts (which are lazy left folds, that appear not to be useful).
633 Performance is significantly better.
634 
635]
636[Performance improvements to Data.Map
637Don Stewart <dons@galois.com>**20100829120245
638 Ignore-this: b4830cddfa6d62e4883f4e0f58ac4e57
639 
640 Applied several standard transformations to improve the performance of
641 code:
642 
643     * Worker/wrapper of all recursive functions with constant arguments
644     * Inlining of all (non-recursive) wrappers
645     * Consistent use of strict keys
646 
647 Average performance improvements across common API (with GHC 6.12.3):
648 
649     * Linux / x86_64 / 2.6Ghz i7        : 48%
650     * Mac OSX 10.5 / x86 / 2 Ghz Xeon   : 36%
651 
652 Graphs and raw data: http://is.gd/eJHIE
653 
654 This patch is (mostly) orthogonal to the algorithmic changes suggested
655 by Milan Straka in his HW 2010 paper:
656 
657     http://research.microsoft.com/~simonpj/papers/containers/containers.pdf
658 
659 Those changes could be added separately, for some additional improvments.
660 
661 Work carried out over 28/29th August, 2010 in Utrecht, NL, by Johan Tibell
662 and Don Stewart.
663 
664]
665[Add a criterion-based benchmark suite for Data.Map
666Don Stewart <dons@galois.com>**20100829114611
667 Ignore-this: ec61668f5bcb78bd15b72e2728c01c19
668 
669 This adds a criterion-based micro-benchmarking suite for Data.Map. It
670 can be used to measure performance improvements for individual top-level
671 functions.
672 
673 Examples here: http://is.gd/eJHIE
674 
675]
676[Add a comprehensive testsuite for Data.Map
677Don Stewart <dons@galois.com>**20100829113545
678 Ignore-this: 891e7fe6bac3523868714ac1ff51c0a3
679 
680 This patch adds a joint quickcheck2 / hunit testsuite, with coverage of
681 91% of top level functions (remaining features are mostly in instances).
682 
683 The coverage data is here:
684     
685     http://code.haskell.org/~dons/tests/containers/hpc_index.html
686 
687 No bugs were found. It includes unit tests for known past bugs
688 (balancing).
689 
690]
691[Oops, get the #ifdef symbol correct.
692Malcolm.Wallace@me.com**20100902081938]
693[Protect a gratuitous GHC-ism with #ifdefs.
694Malcolm.Wallace@me.com**20100902081217]
695[Set Data.Map's delta to 4; fixes #4242
696Ian Lynagh <igloo@earth.li>**20100815131954]
697[Add a test for #4242
698Ian Lynagh <igloo@earth.li>**20100815131856]
699[Add a local type signature
700simonpj@microsoft.com**20100730124447
701 Ignore-this: b581d3f2c80a7a860456d589960f12f2
702]
703[Add type signature in local where clause
704simonpj@microsoft.com**20100727151709
705 Ignore-this: 5929c4156500b25b280eb414b508c508
706]
707[Fix Data.Sequence's breakr, and add a test for it; fixes trac #4157
708Ian Lynagh <igloo@earth.li>**20100704140627]
709[Fix proposal #4109: Make Data.Map.insertWith's strictness consistent
710Ian Lynagh <igloo@earth.li>**20100615133055]
711[Tweak layout to work with the alternative layout rule
712Ian Lynagh <igloo@earth.li>**20091129154519]
713[Disable building Data.Sequence (and dependents) for nhc98.
714Malcolm.Wallace@cs.york.ac.uk**20091124025653
715 There is some subtlety of polymorphically recursive datatypes and
716 type-class defaulting that nhc98's type system barfs over.
717]
718[Fix another instance of non-ghc breakage.
719Malcolm.Wallace@cs.york.ac.uk**20091123092637]
720[Add #ifdef around ghc-only (<$) as member of Functor class.
721Malcolm.Wallace@cs.york.ac.uk**20091123085155]
722[Fix broken code in non-GHC branch of an ifdef.
723Malcolm.Wallace@cs.york.ac.uk**20091123084824]
724[doc bugfix: correct description of index argument
725Ross Paterson <ross@soi.city.ac.uk>**20091028105532
726 Ignore-this: 9790e7bf422c4cb528722c03cfa4fed9
727 
728 As noted by iaefai on the libraries list.
729 
730 Please merge to STABLE.
731]
732[Bump version to 0.3.0.0
733Ian Lynagh <igloo@earth.li>**20090920141847]
734[update base dependency
735Ross Paterson <ross@soi.city.ac.uk>**20090916073125
736 Ignore-this: ad382ffc6c6a18c15364e6c072f19edb
737 
738 The package uses mkNoRepType and Data.Functor, which were not in the
739 stable branch of base-4.
740]
741[add fast version of <$ for Seq
742Ross Paterson <ross@soi.city.ac.uk>**20090916072812
743 Ignore-this: 5a39a7d31d39760ed589790b1118d240
744]
745[new methods for Data.Sequence (proposal #3271)
746Ross Paterson <ross@soi.city.ac.uk>**20090915173324
747 Ignore-this: cf17bedd709a6ab3448fd718dcdf62e7
748 
749 Adds a lot of new methods to Data.Sequence, mostly paralleling those
750 in Data.List.  Several of these are significantly faster than versions
751 implemented with the previous public interface.  In particular, replicate
752 takes O(log n) time and space instead of O(n).
753 (by Louis Wasserman)
754]
755[Fix "Cabal check" warnings
756Ian Lynagh <igloo@earth.li>**20090811215900]
757[TAG 2009-06-25
758Ian Lynagh <igloo@earth.li>**20090625160202]
759Patch bundle hash:
76033c9bf74573ee1d842e7ca38d6efc36ff943b8f3