Commit Graph

75 Commits

Author SHA1 Message Date
Alex Crichton
9a259f4303 Fix fallout of requiring uint indices 2014-04-02 15:56:31 -07:00
bors
b71c02e512 auto merge of #13115 : huonw/rust/rand-errors, r=alexcrichton
move errno -> IoError converter into std, bubble up OSRng errors

Also adds a general errno -> `~str` converter to `std::os`, and makes the failure messages for the things using `OSRng` (e.g. (transitively) the task-local RNG, meaning hashmap initialisation failures aren't such a black box).
2014-04-01 11:11:51 -07:00
Huon Wilson
bc7a2d72a3 rand: bubble up IO messages futher.
The various ...Rng::new() methods can hit IO errors from the OSRng they use,
and it seems sensible to expose them at a higher level. Unfortunately, writing
e.g. `StdRng::new().unwrap()` gives a much poorer error message than if it
failed internally, but this is a problem with all `IoResult`s.
2014-04-01 20:46:10 +11:00
Alex Crichton
8ad7e5481f collections: Switch field privacy as necessary 2014-03-31 15:17:12 -07:00
Brian Anderson
ee052198c5 Rename from_iterator to from_iter for consistency. 2014-03-30 21:45:55 -07:00
Scott Jenkins
edc7ad162c Updated references to extra in libcollections docs 2014-03-30 13:35:54 +01:00
bors
d878df05ad auto merge of #13183 : erickt/rust/remove-list, r=alexcrichton
`collections::list::List` was decided in a [team meeting](https://github.com/mozilla/rust/wiki/Meeting-weekly-2014-03-25) that it was unnecessary, so this PR removes it. Additionally, it removes an old and redundant purity test and fixes some warnings.
2014-03-29 11:41:37 -07:00
Brian Anderson
451e8c1c61 Convert most code to new inner attribute syntax.
Closes #2569
2014-03-28 17:12:21 -07:00
Erick Tryzelaar
a47d52c2f6 collections: remove List
It was decided in a meeting that this module wasn't needed,
and more thought should be put into a persistent collections
library.
2014-03-28 09:13:09 -07:00
Flavio Percoco
81ec1f3c18 Rename Pod into Copy
Summary:
So far, we've used the term POD "Plain Old Data" to refer to types that
can be safely copied. However, this term is not consistent with the
other built-in bounds that use verbs instead. This patch renames the Pod
kind into Copy.

RFC: 0003-opt-in-builtin-traits

Test Plan: make check

Reviewers: cmr

Differential Revision: http://phabricator.octayn.net/D3
2014-03-28 10:34:02 +01:00
Marvin Löbel
6200e761f0 Changed iter::Extendable and iter::FromIterator to take a Iterator by value 2014-03-25 21:49:55 +01:00
bors
903e83889a auto merge of #13102 : huonw/rust/totaleq-deriving, r=thestinger
std: remove the `equals` method from `TotalEq`.

`TotalEq` is now just an assertion about the `Eq` impl of a
type (i.e. `==` is a total equality if a type implements `TotalEq`) so
the extra method is just confusing.

Also, a new method magically appeared as a hack to allow deriving to
assert that the contents of a struct/enum are also TotalEq, because the
deriving infrastructure makes it very hard to do anything but create a
trait method. (You didn't hear about this horrible work-around from me
:(.)
2014-03-23 08:36:51 -07:00
Huon Wilson
f6db0ef946 std: remove the equals method from TotalEq.
`TotalEq` is now just an assertion about the `Eq` impl of a
type (i.e. `==` is a total equality if a type implements `TotalEq`) so
the extra method is just confusing.

Also, a new method magically appeared as a hack to allow deriving to
assert that the contents of a struct/enum are also TotalEq, because the
deriving infrastructure makes it very hard to do anything but create a
trait method. (You didn't hear about this horrible work-around from me
:(.)
2014-03-23 23:48:10 +11:00
Flavio Percoco
576e36e674 Register new snapshots 2014-03-23 11:37:31 +01:00
Daniel Micay
3829ac2a52 use TotalEq for HashMap
Closes #5283
2014-03-23 01:59:11 -04:00
Alex Crichton
11ac4df4d2 Register new snapshots 2014-03-20 11:02:26 -07:00
Alex Crichton
da3625161d Removing imports of std::vec_ng::Vec
It's now in the prelude.
2014-03-20 09:30:14 -07:00
Daniel Micay
14f656d1a7 rename std::vec_ng -> std::vec
Closes #12771
2014-03-20 04:25:32 -04:00
Daniel Micay
ce620320a2 rename std::vec -> std::slice
Closes #12702
2014-03-20 01:30:27 -04:00
Alex Crichton
cc6ec8df95 log: Introduce liblog, the old std::logging
This commit moves all logging out of the standard library into an external
crate. This crate is the new crate which is responsible for all logging macros
and logging implementation. A few reasons for this change are:

* The crate map has always been a bit of a code smell among rust programs. It
  has difficulty being loaded on almost all platforms, and it's used almost
  exclusively for logging and only logging. Removing the crate map is one of the
  end goals of this movement.

* The compiler has a fair bit of special support for logging. It has the
  __log_level() expression as well as generating a global word per module
  specifying the log level. This is unfairly favoring the built-in logging
  system, and is much better done purely in libraries instead of the compiler
  itself.

* Initialization of logging is much easier to do if there is no reliance on a
  magical crate map being available to set module log levels.

* If the logging library can be written outside of the standard library, there's
  no reason that it shouldn't be. It's likely that we're not going to build the
  highest quality logging library of all time, so third-party libraries should
  be able to provide just as high-quality logging systems as the default one
  provided in the rust distribution.

With a migration such as this, the change does not come for free. There are some
subtle changes in the behavior of liblog vs the previous logging macros:

* The core change of this migration is that there is no longer a physical
  log-level per module. This concept is still emulated (it is quite useful), but
  there is now only a global log level, not a local one. This global log level
  is a reflection of the maximum of all log levels specified. The previously
  generated logging code looked like:

    if specified_level <= __module_log_level() {
        println!(...)
    }

  The newly generated code looks like:

    if specified_level <= ::log::LOG_LEVEL {
        if ::log::module_enabled(module_path!()) {
            println!(...)
        }
    }

  Notably, the first layer of checking is still intended to be "super fast" in
  that it's just a load of a global word and a compare. The second layer of
  checking is executed to determine if the current module does indeed have
  logging turned on.

  This means that if any module has a debug log level turned on, all modules
  with debug log levels get a little bit slower (they all do more expensive
  dynamic checks to determine if they're turned on or not).

  Semantically, this migration brings no change in this respect, but
  runtime-wise, this will have a perf impact on some code.

* A `RUST_LOG=::help` directive will no longer print out a list of all modules
  that can be logged. This is because the crate map will no longer specify the
  log levels of all modules, so the list of modules is not known. Additionally,
  warnings can no longer be provided if a malformed logging directive was
  supplied.

The new "hello world" for logging looks like:

    #[phase(syntax, link)]
    extern crate log;

    fn main() {
        debug!("Hello, world!");
    }
2014-03-15 22:26:36 -07:00
Steven Fackler
9106c15ffd Add rustdoc html crate info 2014-03-15 14:26:12 -07:00
bors
29756a3b76 auto merge of #12867 : alexcrichton/rust/issue-12860, r=thestinger
This switches a "tail call" to a manual loop to get around LLVM not optimizing
to a tail call.

Close #12860
2014-03-14 02:01:34 -07:00
bors
6c895d1d58 auto merge of #12864 : huonw/rust/hash-docs, r=alexcrichton
collections: move hashmap's example to the struct.

Most people go straight to the struct, not looking at the module, so the
example was well hidden.
2014-03-14 00:41:34 -07:00
Huon Wilson
62792f09f2 lint: add lint for use of a ~[T].
This is useless at the moment (since pretty much every crate uses
`~[]`), but should help avoid regressions once completely removed from a
crate.
2014-03-14 11:28:39 +11:00
Alex Crichton
05c991c4bb collections: Don't recurse in hashmap robin_hood
This switches a "tail call" to a manual loop to get around LLVM not optimizing
to a tail call.

Close #12860
2014-03-13 09:50:19 -07:00
Huon Wilson
d06266995c collections: move hashmap's example to the struct.
Most people go straight to the struct, not looking at the module, so the
example was well hidden.
2014-03-13 22:31:56 +11:00
bors
2eebeb8137 auto merge of #12081 : cgaebel/rust/robinhood-hashing, r=alexcrichton
Partially addresses #11783.

Previously, rust's hashtable was totally unoptimized. It used an Option
per key-value pair, and used very naive open allocation.

The old hashtable had very high variance in lookup time. For an example,
see the 'find_nonexisting' benchmark below. This is fixed by keys in
'lucky' spots with a low probe sequence length getting their good spots
stolen by keys with long probe sequence lengths. This reduces hashtable
probe length variance, while maintaining the same mean.

Also, other optimization liberties were taken. Everything is as cache
aware as possible, and this hashtable should perform extremely well for
both large and small keys and values.

Benchmarks:

```
comprehensive_old_hashmap         378 ns/iter (+/- 8)
comprehensive_new_hashmap         206 ns/iter (+/- 4)
1.8x faster

old_hashmap_as_queue              238 ns/iter (+/- 8)
new_hashmap_as_queue              119 ns/iter (+/- 2)
2x faster

old_hashmap_insert                172 ns/iter (+/- 8)
new_hashmap_insert                146 ns/iter (+/- 11)
1.17x faster

old_hashmap_find_existing         50 ns/iter (+/- 12)
new_hashmap_find_existing         35 ns/iter (+/- 6)
1.43x faster

old_hashmap_find_notexisting      49 ns/iter (+/- 49)
new_hashmap_find_notexisting      34 ns/iter (+/- 4)
1.44x faster

Memory usage of old hashtable (64-bit assumed):

aligned(8+sizeof(Option)+sizeof(K)+sizeof(V))/0.75 + 48ish bytes

Memory usage of new hashtable:

(aligned(sizeof(K))
+ aligned(sizeof(V))
+ 8)/0.9 + 112ish bytes

Timing of building librustc:

compile_and_link: x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc
time: 0.457 s   parsing
time: 0.028 s   gated feature checking
time: 0.000 s   crate injection
time: 0.108 s   configuration 1
time: 1.049 s   expansion
time: 0.219 s   configuration 2
time: 0.222 s   maybe building test harness
time: 0.223 s   prelude injection
time: 0.268 s   assinging node ids and indexing ast
time: 0.075 s   external crate/lib resolution
time: 0.026 s   language item collection
time: 1.016 s   resolution
time: 0.038 s   lifetime resolution
time: 0.000 s   looking for entry point
time: 0.030 s   looking for macro registrar
time: 0.061 s   freevar finding
time: 0.138 s   region resolution
time: 0.110 s   type collecting
time: 0.072 s   variance inference
time: 0.126 s   coherence checking
time: 9.110 s   type checking
time: 0.186 s   const marking
time: 0.049 s   const checking
time: 0.418 s   privacy checking
time: 0.057 s   effect checking
time: 0.033 s   loop checking
time: 1.293 s   compute moves
time: 0.182 s   match checking
time: 0.242 s   liveness checking
time: 0.866 s   borrow checking
time: 0.150 s   kind checking
time: 0.013 s   reachability checking
time: 0.175 s   death checking
time: 0.461 s   lint checking
time: 13.112 s  translation
  time: 4.352 s llvm function passes
  time: 96.702 s    llvm module passes
  time: 50.574 s    codegen passes
time: 154.611 s LLVM passes
  time: 2.821 s running linker
time: 15.750 s  linking


compile_and_link: x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc
time: 0.422 s   parsing
time: 0.031 s   gated feature checking
time: 0.000 s   crate injection
time: 0.126 s   configuration 1
time: 1.014 s   expansion
time: 0.251 s   configuration 2
time: 0.249 s   maybe building test harness
time: 0.273 s   prelude injection
time: 0.279 s   assinging node ids and indexing ast
time: 0.076 s   external crate/lib resolution
time: 0.033 s   language item collection
time: 1.028 s   resolution
time: 0.036 s   lifetime resolution
time: 0.000 s   looking for entry point
time: 0.029 s   looking for macro registrar
time: 0.063 s   freevar finding
time: 0.133 s   region resolution
time: 0.111 s   type collecting
time: 0.077 s   variance inference
time: 0.565 s   coherence checking
time: 8.953 s   type checking
time: 0.176 s   const marking
time: 0.050 s   const checking
time: 0.401 s   privacy checking
time: 0.063 s   effect checking
time: 0.032 s   loop checking
time: 1.291 s   compute moves
time: 0.172 s   match checking
time: 0.249 s   liveness checking
time: 0.831 s   borrow checking
time: 0.121 s   kind checking
time: 0.013 s   reachability checking
time: 0.179 s   death checking
time: 0.503 s   lint checking
time: 14.385 s  translation
  time: 4.495 s llvm function passes
  time: 92.234 s    llvm module passes
  time: 51.172 s    codegen passes
time: 150.809 s LLVM passes
  time: 2.542 s running linker
time: 15.109 s  linking
```

BUT accesses are much more cache friendly. In fact, if the probe
sequence length is below 8, only two cache lines worth of hashes will be
pulled into cache. This is unlike the old version which would have to
stride over the stoerd keys and values, and would be more cache
unfriendly the bigger the stored values got.

And did you notice the higher load factor? We can now reasonably get a
load factor of 0.9 with very good performance.

Please review this very closely. This is my first major contribution to Rust. Sorry for the ugly diff!
2014-03-12 18:06:47 -07:00
Clark Gaebel
5bdbd21009 Performance-oriented hashtable.
Previously, rust's hashtable was totally unoptimized. It used an Option
per key-value pair, and used very naive open allocation.

The old hashtable had very high variance in lookup time. For an example,
see the 'find_nonexisting' benchmark below. This is fixed by keys in
'lucky' spots with a low probe sequence length getting their good spots
stolen by keys with long probe sequence lengths. This reduces hashtable
probe length variance, while maintaining the same mean.

Also, other optimization liberties were taken. Everything is as cache
aware as possible, and this hashtable should perform extremely well for
both large and small keys and values.

Benchmarks:

comprehensive_old_hashmap         378 ns/iter (+/- 8)
comprehensive_new_hashmap         206 ns/iter (+/- 4)
1.8x faster

old_hashmap_as_queue              238 ns/iter (+/- 8)
new_hashmap_as_queue              119 ns/iter (+/- 2)
2x faster

old_hashmap_insert                172 ns/iter (+/- 8)
new_hashmap_insert                146 ns/iter (+/- 11)
1.17x faster

old_hashmap_find_existing         50 ns/iter (+/- 12)
new_hashmap_find_existing         35 ns/iter (+/- 6)
1.43x faster

old_hashmap_find_notexisting      49 ns/iter (+/- 49)
new_hashmap_find_notexisting      34 ns/iter (+/- 4)
1.44x faster

Memory usage of old hashtable (64-bit assumed):

aligned(8+sizeof(K)+sizeof(V))/0.75 + 6 words

Memory usage of new hashtable:

(aligned(sizeof(K))
+ aligned(sizeof(V))
+ 8)/0.9 + 6.5 words

BUT accesses are much more cache friendly. In fact, if the probe
sequence length is below 8, only two cache lines worth of hashes will be
pulled into cache. This is unlike the old version which would have to
stride over the stoerd keys and values, and would be more cache
unfriendly the bigger the stored values got.

And did you notice the higher load factor? We can now reasonably get a
load factor of 0.9 with very good performance.
2014-03-12 18:30:11 -04:00
Erick Tryzelaar
9959188d0e Use generic impls for Hash 2014-03-12 13:39:47 -07:00
Huon Wilson
198caa87cd Update users for the std::rand -> librand move. 2014-03-12 11:31:43 +11:00
Daniel Micay
4d7d101a76 create a sensible comparison trait hierarchy
* `Ord` inherits from `Eq`
* `TotalOrd` inherits from `TotalEq`
* `TotalOrd` inherits from `Ord`
* `TotalEq` inherits from `Eq`

This is a partial implementation of #12517.
2014-03-07 22:45:22 -05:00
Alex Crichton
42389b7069 collections: Correct with_capacity_and_hasher
The arguments were accidentally swapped in the wrong order.

Closes #12743
2014-03-06 18:07:52 -08:00
Kang Seonghoon
1c52c81846 fix typos with with repeated words, just like this sentence. 2014-03-06 20:19:14 +09:00
Alex Crichton
02882fbd7e std: Change assert_eq!() to use {} instead of {:?}
Formatting via reflection has been a little questionable for some time now, and
it's a little unfortunate that one of the standard macros will silently use
reflection when you weren't expecting it. This adds small bits of code bloat to
libraries, as well as not always being necessary. In light of this information,
this commit switches assert_eq!() to using {} in the error message instead of
{:?}.

In updating existing code, there were a few error cases that I encountered:

* It's impossible to define Show for [T, ..N]. I think DST will alleviate this
  because we can define Show for [T].
* A few types here and there just needed a #[deriving(Show)]
* Type parameters needed a Show bound, I often moved this to `assert!(a == b)`
* `Path` doesn't implement `Show`, so assert_eq!() cannot be used on two paths.
  I don't think this is much of a regression though because {:?} on paths looks
  awful (it's a byte array).

Concretely speaking, this shaved 10K off a 656K binary. Not a lot, but sometime
significant for smaller binaries.
2014-02-28 23:01:54 -08:00
bors
31e9c947a3 auto merge of #12544 : erickt/rust/hash, r=acrichto
This PR allows `HashMap`s to work with custom hashers. Also with this patch are:

* a couple generic implementations of `Hash` for a variety of types.
* added `Default`, `Clone` impls to the hashers.
* added a `HashMap::with_hasher()` constructor.
2014-02-28 00:26:34 -08:00
Erick Tryzelaar
72b5e30f6c collections: allow HashMap to work with generic hashers 2014-02-27 19:02:52 -08:00
Bruno de Oliveira Abinader
4da6d041c2 Replaced list::push() with unshift() based on List<T> 2014-02-27 08:36:07 -04:00
Bruno de Oliveira Abinader
1c27c90119 Refactored list::append() to be based on List<T> 2014-02-27 08:36:06 -04:00
Bruno de Oliveira Abinader
65f1993230 Refactored list::tail() to be based on List<T> 2014-02-27 08:35:47 -04:00
Bruno de Oliveira Abinader
fed034c402 Refactored list::head() to be based on List<T> 2014-02-27 08:35:47 -04:00
Bruno de Oliveira Abinader
45fd63a8b7 Replaced list::has() with list::contains() 2014-02-27 08:35:47 -04:00
Bruno de Oliveira Abinader
223f309fc3 Removed deprecated list::{iter,each}() functions 2014-02-27 08:35:47 -04:00
Bruno de Oliveira Abinader
a14d72d49e Implemented list::is_empty() based on Container trait 2014-02-27 08:35:47 -04:00
Bruno de Oliveira Abinader
e589fcffcc Implemented list::len() based on Container trait 2014-02-27 08:35:46 -04:00
Bruno de Oliveira Abinader
197116d7ce Removed list::any() in favor of iter().any() 2014-02-27 08:35:46 -04:00
Bruno de Oliveira Abinader
d681907064 Removed list::find() in favor of iter().find() 2014-02-27 08:35:46 -04:00
Bruno de Oliveira Abinader
a09a4b882d Removed list::foldl() in favor of iter().fold() 2014-02-27 08:35:45 -04:00
Bruno de Oliveira Abinader
52524bfe88 Implemented Items<'a, T> for List<T> 2014-02-27 08:35:18 -04:00
Bruno de Oliveira Abinader
2b362768ff Modified list::from_vec() to return List<T> 2014-02-27 08:35:17 -04:00
Bruno de Oliveira Abinader
1e6151a770 Renamed variables 2014-02-27 08:35:16 -04:00