rust/src/libstd/io
bors 75a39e0fb8 auto merge of #15399 : kballard/rust/rewrite_local_data, r=alexcrichton
This was motivated by a desire to remove allocation in the common
pattern of

    let old = key.replace(None)
    do_something();
    key.replace(old);

This also switched the map representation from a Vec to a TreeMap. A Vec
may be reasonable if there's only a couple TLD keys, but a TreeMap
provides better behavior as the number of keys increases.

Like the Vec, this TreeMap implementation does not shrink the container
when a value is removed. Unlike Vec, this TreeMap implementation cannot
reuse an empty node for a different key. Therefore any key that has been
inserted into the TLD at least once will continue to take up space in
the Map until the task ends. The expectation is that the majority of
keys that are inserted into TLD will be expected to have a value for
most of the rest of the task's lifetime. If this assumption is wrong,
there are two reasonable ways to fix this that could be implemented in
the future:

1. Provide an API call to either remove a specific key from the TLD and
   destruct its node (e.g. `remove()`), or instead to explicitly clean
   up all currently-empty nodes in the map (e.g. `compact()`). This is
   simple, but requires the user to explicitly call it.
2. Keep track of the number of empty nodes in the map and when the map
   is mutated (via `replace()`), if the number of empty nodes passes
   some threshold, compact it automatically. Alternatively, whenever a
   new key is inserted that hasn't been used before, compact the map at
   that point.

---

Benchmarks:

I ran 3 benchmarks. tld_replace_none just replaces the tld key with None
repeatedly. tld_replace_some replaces it with Some repeatedly. And
tld_replace_none_some simulates the common behavior of replacing with
None, then replacing with the previous value again (which was a Some).

Old implementation:

    test tld_replace_none      ... bench:        20 ns/iter (+/- 0)
    test tld_replace_none_some ... bench:        77 ns/iter (+/- 4)
    test tld_replace_some      ... bench:        57 ns/iter (+/- 2)

New implementation:

    test tld_replace_none      ... bench:        11 ns/iter (+/- 0)
    test tld_replace_none_some ... bench:        23 ns/iter (+/- 0)
    test tld_replace_some      ... bench:        12 ns/iter (+/- 0)
2014-07-31 23:16:33 +00:00
..
net Tweak error reporting in io::net::tcp tests 2014-07-31 13:14:06 -07:00
buffered.rs Add a ton of ignore-lexer-test 2014-07-21 18:38:40 -07:00
comm_adapters.rs librustc: Match trait self types exactly. 2014-06-28 11:18:37 -07:00
extensions.rs collections: Move push/pop to MutableSeq 2014-07-23 13:20:10 -07:00
fs.rs auto merge of #15915 : erickt/rust/master, r=alexcrichton 2014-07-30 14:41:18 +00:00
mem.rs std: Make MemWriter clonable 2014-07-29 16:32:07 -07:00
mod.rs Implement Default for std::io::FilePermission 2014-07-30 16:05:24 -04:00
pipe.rs Stabilization for owned (now boxed) and cell 2014-07-13 12:52:51 -07:00
process.rs Fix errors 2014-07-15 20:34:16 +02:00
result.rs De-~[] Mem{Reader,Writer} 2014-04-06 15:40:01 -07:00
signal.rs collections: Move push/pop to MutableSeq 2014-07-23 13:20:10 -07:00
stdio.rs Stabilization for owned (now boxed) and cell 2014-07-13 12:52:51 -07:00
tempfile.rs librustc: Stop desugaring for expressions and translate them directly. 2014-07-24 18:58:12 -07:00
test.rs Rename all raw pointers as necessary 2014-06-28 11:53:58 -07:00
timer.rs Stabilization for owned (now boxed) and cell 2014-07-13 12:52:51 -07:00
util.rs Stabilization for owned (now boxed) and cell 2014-07-13 12:52:51 -07:00