Re: [rust-dev] Scheduler and I/O work items for the summer

2013-06-01 Thread Matthieu Monrocq
On Sat, Jun 1, 2013 at 8:35 PM, Vadim  wrote:

>
> On Sat, Jun 1, 2013 at 7:47 AM, Matthieu Monrocq <
> matthieu.monr...@gmail.com> wrote:
>
>>
>>  1. Futures use a custom free-list allocator for performance.

>>>
>> I don't see why Futures could not be allocated on the stack ?
>>
>> Since Rust is move aware and has value types, it seems to me this should
>> be possible.
>>
>
> Because I/O manager needs to know where that future is in order to fill in
> the result.
>
> Perhaps it's possible to have a stack-allocated future objects that
> consist of just a raw pointer to a block owned by the I/O manager.  But
> these would need to have by-move semantics in order to emulate behavior of
> unique pointers.   I am not entirely sure how by-move vs by-copy is
> decided, but according to 
> thisRust 
> would choose by-copy.
>
> Vadim
>
>

Actually, I was more thinking of reserving space on the stack for the
return value and have to IO layer write directly into that space (akin to
C++'s Return Value Optimization).

However I might be stumbling on ABI issues here, since it essentially means
that the compiler transforms "Args... -> ~Future" into "Args..., &mut
Future -> ()".

-- Matthieu
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Mutability and borrowing

2013-06-01 Thread Ziad Hatahet
True. I suppose I meant generic and memory efficient at the same time. I
guess it shouldn't be too much of a hassle to implement the specialized
case of this function if memory is absolutely critical.

Thanks

--
Ziad


On Sat, Jun 1, 2013 at 10:03 PM, Abhijeet Gaiha wrote:

> The 'copy' parameter is the most generic way for the client to handle this
> situation.
>
> --
> Abhijeet Gaiha
> http://about.me/abhijeet.gaiha
>
> On Sunday, 2 June 2013 at 10:32 AM, Ziad Hatahet wrote:
>
> Thanks everyone. I actually thought about the two suggestions before
> posting. I thought there might be some common paradigm for this in the
> language though.
>
> So I take it that implementing a += operator overload function would not
> have a generic way to handle the case where the same parameter is passed on
> both sides?
>
>
> --
> Ziad
>
>
> On Sat, Jun 1, 2013 at 9:42 PM, Tim Chevalier wrote:
>
> On Sat, Jun 1, 2013 at 9:33 PM, Ziad Hatahet  wrote:
> > I have the following function:
> >
> > fn add_equal(x: &mut Complex, y: &Complex) {
> > x.real += y.real;
> > x.imag += y.imag;
> > }
> >
> > Calling the function with the same variable being passed to both
> arguments
> > (i.e. add_equal(&mut c, &c)), results in the compile error:
> >
> > error: cannot borrow `c` as immutable because it is also borrowed as
> mutable
> >
> > I am guessing this is to avoid aliasing issues? What is the way around
> this?
> >
>
> You can copy y instead of passing a reference to it:
> fn add_equal(x: &mut Complex, y: Complex) { ...
>
> Of course, that means that at the call site, you will have to write
> something like add_equal(&mut c, copy c).
>
> Unless you want to write a function that just takes one argument and
> doubles it, like Abhijeet suggested, I don't know of another way
> around this.
>
> Cheers,
> Tim
>
>
> --
> Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt
> "Not a riot, it's a rebellion." -- Boots Riley
> "Attention Bros and Trolls: When I call out your spew, I'm not angry,
> I'm defiant." -- Reg Braithwaite
>
>
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
>
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Mutability and borrowing

2013-06-01 Thread Abhijeet Gaiha
The 'copy' parameter is the most generic way for the client to handle this 
situation.

-- 
Abhijeet Gaiha
http://about.me/abhijeet.gaiha


On Sunday, 2 June 2013 at 10:32 AM, Ziad Hatahet wrote:

> Thanks everyone. I actually thought about the two suggestions before posting. 
> I thought there might be some common paradigm for this in the language though.
> 
> So I take it that implementing a += operator overload function would not have 
> a generic way to handle the case where the same parameter is passed on both 
> sides?
> 
> 
> --
> Ziad 
> 
> On Sat, Jun 1, 2013 at 9:42 PM, Tim Chevalier  (mailto:catamorph...@gmail.com)> wrote:
> > On Sat, Jun 1, 2013 at 9:33 PM, Ziad Hatahet  > (mailto:hata...@gmail.com)> wrote:
> > > I have the following function:
> > >
> > > fn add_equal(x: &mut Complex, y: &Complex) {
> > > x.real += y.real;
> > > x.imag += y.imag;
> > > }
> > >
> > > Calling the function with the same variable being passed to both arguments
> > > (i.e. add_equal(&mut c, &c)), results in the compile error:
> > >
> > > error: cannot borrow `c` as immutable because it is also borrowed as 
> > > mutable
> > >
> > > I am guessing this is to avoid aliasing issues? What is the way around 
> > > this?
> > >
> > 
> > You can copy y instead of passing a reference to it:
> > fn add_equal(x: &mut Complex, y: Complex) { ...
> > 
> > Of course, that means that at the call site, you will have to write
> > something like add_equal(&mut c, copy c).
> > 
> > Unless you want to write a function that just takes one argument and
> > doubles it, like Abhijeet suggested, I don't know of another way
> > around this.
> > 
> > Cheers,
> > Tim
> > 
> > 
> > --
> > Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt
> > "Not a riot, it's a rebellion." -- Boots Riley
> > "Attention Bros and Trolls: When I call out your spew, I'm not angry,
> > I'm defiant." -- Reg Braithwaite
> 
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org (mailto:Rust-dev@mozilla.org)
> https://mail.mozilla.org/listinfo/rust-dev
> 
> 


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Mutability and borrowing

2013-06-01 Thread Ziad Hatahet
Thanks everyone. I actually thought about the two suggestions before
posting. I thought there might be some common paradigm for this in the
language though.

So I take it that implementing a += operator overload function would not
have a generic way to handle the case where the same parameter is passed on
both sides?


--
Ziad


On Sat, Jun 1, 2013 at 9:42 PM, Tim Chevalier wrote:

> On Sat, Jun 1, 2013 at 9:33 PM, Ziad Hatahet  wrote:
> > I have the following function:
> >
> > fn add_equal(x: &mut Complex, y: &Complex) {
> > x.real += y.real;
> > x.imag += y.imag;
> > }
> >
> > Calling the function with the same variable being passed to both
> arguments
> > (i.e. add_equal(&mut c, &c)), results in the compile error:
> >
> > error: cannot borrow `c` as immutable because it is also borrowed as
> mutable
> >
> > I am guessing this is to avoid aliasing issues? What is the way around
> this?
> >
>
> You can copy y instead of passing a reference to it:
> fn add_equal(x: &mut Complex, y: Complex) { ...
>
> Of course, that means that at the call site, you will have to write
> something like add_equal(&mut c, copy c).
>
> Unless you want to write a function that just takes one argument and
> doubles it, like Abhijeet suggested, I don't know of another way
> around this.
>
> Cheers,
> Tim
>
>
> --
> Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt
> "Not a riot, it's a rebellion." -- Boots Riley
> "Attention Bros and Trolls: When I call out your spew, I'm not angry,
> I'm defiant." -- Reg Braithwaite
>
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Mutability and borrowing

2013-06-01 Thread Tim Chevalier
On Sat, Jun 1, 2013 at 9:33 PM, Ziad Hatahet  wrote:
> I have the following function:
>
> fn add_equal(x: &mut Complex, y: &Complex) {
> x.real += y.real;
> x.imag += y.imag;
> }
>
> Calling the function with the same variable being passed to both arguments
> (i.e. add_equal(&mut c, &c)), results in the compile error:
>
> error: cannot borrow `c` as immutable because it is also borrowed as mutable
>
> I am guessing this is to avoid aliasing issues? What is the way around this?
>

You can copy y instead of passing a reference to it:
fn add_equal(x: &mut Complex, y: Complex) { ...

Of course, that means that at the call site, you will have to write
something like add_equal(&mut c, copy c).

Unless you want to write a function that just takes one argument and
doubles it, like Abhijeet suggested, I don't know of another way
around this.

Cheers,
Tim


-- 
Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt
"Not a riot, it's a rebellion." -- Boots Riley
"Attention Bros and Trolls: When I call out your spew, I'm not angry,
I'm defiant." -- Reg Braithwaite
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Mutability and borrowing

2013-06-01 Thread Abhijeet Gaiha
Trying to concurrently borrow a value twice is never going to work. 
You could write a function like "double" for such a situation.

-- 
Abhijeet Gaiha
http://about.me/abhijeet.gaiha


On Sunday, 2 June 2013 at 10:03 AM, Ziad Hatahet wrote:

> I have the following function:
> 
> fn add_equal(x: &mut Complex, y: &Complex) {
> x.real += y.real;
> x.imag += y.imag;
> }
> 
> Calling the function with the same variable being passed to both arguments 
> (i.e. add_equal(&mut c, &c)), results in the compile error:
> 
> error: cannot borrow `c` as immutable because it is also borrowed as mutable
> 
> I am guessing this is to avoid aliasing issues? What is the way around this?
> 
> Thanks
> 
> --
> Ziad 
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org (mailto:Rust-dev@mozilla.org)
> https://mail.mozilla.org/listinfo/rust-dev
> 
> 


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Mutability and borrowing

2013-06-01 Thread Ziad Hatahet
I have the following function:

fn add_equal(x: &mut Complex, y: &Complex) {
x.real += y.real;
x.imag += y.imag;
}

Calling the function with the same variable being passed to both arguments
(i.e. add_equal(&mut c, &c)), results in the compile error:

error: cannot borrow `c` as immutable because it is also borrowed as mutable

I am guessing this is to avoid aliasing issues? What is the way around this?

Thanks

--
Ziad
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Traits & "mod"

2013-06-01 Thread Tom Lee
Hey folks,

A work colleague is trying to pick up some Rust & we were both
surprised by the following:

// some_mod.rs

pub trait SomeTrait {
pub fn foo(&self) -> ~str;
}

pub struct SomeStruct {
name: ~str
}

impl SomeTrait for SomeStruct {
pub fn foo(&self) -> ~str {
self.name.clone()
}
}

impl SomeStruct {
pub fn new(name: &str) -> SomeStruct {
SomeStruct { name: name.to_owned() }
}
}

// some_use.rs

mod some_mod;

fn main() {

  let inst = some_mod::SomeStruct::new("test");

  println(inst.foo());

}


This fails with a compile error because the compiler can't "see"
some_mod::SomeTrait in the scope of some_use.rs:

some_use.rs:5:4: 6:1 error: type `some_mod::SomeStruct` does not
implement any method in scope named `foo`
some_use.rs:5 inst.foo()
some_use.rs:6 }

This is fixed by adding "use some_mod::SomeTrait" at the start of
some_use.rs. It's as though traits need to be in the same scope as
code that expects to make use of their behaviour (where I'd expect the
behaviour would be associated with the implementation for the "self"
type).

My question is: is this intended behaviour? If not, what's the
expected behaviour & is there an outstanding issue for this?

Appreciate any clarification!

Cheers,
Tom

--
Tom Lee / http://tomlee.co / @tglee
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Scheduler and I/O work items for the summer

2013-06-01 Thread Vadim
On Sat, Jun 1, 2013 at 7:47 AM, Matthieu Monrocq  wrote:

>
>  1. Futures use a custom free-list allocator for performance.
>>>
>>
> I don't see why Futures could not be allocated on the stack ?
>
> Since Rust is move aware and has value types, it seems to me this should
> be possible.
>

Because I/O manager needs to know where that future is in order to fill in
the result.

Perhaps it's possible to have a stack-allocated future objects that consist
of just a raw pointer to a block owned by the I/O manager.  But these would
need to have by-move semantics in order to emulate behavior of unique
pointers.   I am not entirely sure how by-move vs by-copy is decided, but
according to 
thisRust
would choose by-copy.

Vadim
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Scheduler and I/O work items for the summer

2013-06-01 Thread Matthieu Monrocq
On Sat, Jun 1, 2013 at 3:43 PM, Thad Guidry  wrote:

>
>
>> I know that Rust currently doesn't currently support this, but what if
>> futures could use a custom allocator?   Then it could work like this:
>>
>> 1. Futures use a custom free-list allocator for performance.
>>
>
I don't see why Futures could not be allocated on the stack ?

Since Rust is move aware and has value types, it seems to me this should be
possible.

-- Matthieu


> 2. The I/O request allocates new future object, registers uv event, then
>> returns unique pointer to the future to its' caller.  However I/O manager
>> retains internal reference to the future, so that it can be resolved once
>> I/O completes.
>> 3. The future object also has a flag indicating that there's an
>> outstanding I/O, so if caller drops the reference to it, it won't be
>> returned to the free list until I/O completes.
>> 4. When I/O is complete, the future get resolved and all attached
>> continuations are run.
>>
>>
>> Vadim
>>
>>
> Brian,
>
> Vadim described the idea fairly well there with the meat of my idea being
> # 2.  I was just trying to describe the scenario that # 4 be able to happen
> only when all the registered event(s) happen (not just 1 blocking step but
> perhaps many blocking steps).
>
> I would not know where to start mocking something like that with Rust
> yet... still beginning.
>
> --
> -Thad
> http://www.freebase.com/view/en/thad_guidry
>
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Scheduler and I/O work items for the summer

2013-06-01 Thread Thad Guidry
>
> I know that Rust currently doesn't currently support this, but what if
> futures could use a custom allocator?   Then it could work like this:
>
> 1. Futures use a custom free-list allocator for performance.
> 2. The I/O request allocates new future object, registers uv event, then
> returns unique pointer to the future to its' caller.  However I/O manager
> retains internal reference to the future, so that it can be resolved once
> I/O completes.
> 3. The future object also has a flag indicating that there's an
> outstanding I/O, so if caller drops the reference to it, it won't be
> returned to the free list until I/O completes.
> 4. When I/O is complete, the future get resolved and all attached
> continuations are run.
>
>
> Vadim
>
>
Brian,

Vadim described the idea fairly well there with the meat of my idea being #
2.  I was just trying to describe the scenario that # 4 be able to happen
only when all the registered event(s) happen (not just 1 blocking step but
perhaps many blocking steps).

I would not know where to start mocking something like that with Rust
yet... still beginning.

-- 
-Thad
http://www.freebase.com/view/en/thad_guidry
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Question about lifetimes in type parameters

2013-06-01 Thread Niko Matsakis
Ah, one thouht, you may want to be more careful with the def'n of IterBytes
on MapKey to be sure that the hashcodes are the same.



Niko

On Sat, Jun 01, 2013 at 06:46:00AM -0400, Niko Matsakis wrote:
> OK, I finally got a chance to take a look. Indeed, this is not a bug,
> I just misunderstood what was going on. The problem is that the key is
> `&'b [u8]` but you can't supply precisely that type, because the key
> you are using to do th elookup has a shorter lifetime. This is true and
> the type checker is right to complain.
> 
> What you want is to do in these situations is to use the `find_equiv`
> method, which demands a key that is not necessarily the *same* type as
> what is in the map but just one comparable to it. Unfortunately, we
> don't have an equivalence for two slices of unequal lifetimes right
> now (and we can't right one at the moment due to some limitations that
> I am supposed to be lifting). Annoyingly, we also don't have an
> equivalence from ~[u8] to &[u8], only in the reverse direction. We
> should fix this, but usually people have ~[u8] as the key and &[u8] as
> the equivalent lookup key, not the other way around.
> 
> However, you can workaround this limitation using a "new type" struct.
> Here is a version that works. The main trick is to add a temporary
> type `MapKey` for which we can define the `Equiv` trait so that it can
> be compared to the slices that are in your table.
> 
> 
> ```
> extern mod extra;
> use std::vec;
> use std::hashmap::*;
> use std::os;
> use std::str;
> use std::uint;
> use std::cmp::eq;
> 
> #[deriving(IterBytes)]
> struct MapKey(~[u8]);
> impl<'self> Equiv<&'self [u8]> for MapKey {
> fn equiv(&self, other: & &'self [u8]) -> bool {
> let slice1: &[u8] = **self;
> let slice2: &[u8] = *other;
> slice1 == slice2
> }
> }
> 
> pub fn with_mmap_file_contents(filename : &str, f : &fn(v : &[u8]) -> U) 
> -> U {
> fail!()
> }
> 
> pub fn each_combination(values : &[T], r : uint, fun : &fn(combo : 
> &[T]) -> bool) -> bool {
> fail!()
> }
> 
> fn get_letters(s : &str) -> ~[u8] {
> let mut t = str::to_chars(s);
> extra::sort::quick_sort(t, |a,b| *a <= *b);
> return vec::from_fn(t.len(), |i| t[i] as u8);
> }
> 
> fn line_map<'b>(buffer : &'b [u8]) -> ~HashMap<&'b [u8],&'b [u8]> {
> let length = buffer.len();
> let mut map = ~HashMap::new();
> let mut i = 0;
> while i < length {
> let mut j = i;
> while j < length && buffer[j] != ' ' as u8 { j += 1; }
> let mut k = j+1;
> while k < length && buffer[k] != '\n' as u8 { k += 1; }
> map.insert(vec::slice(buffer, i, j), vec::slice(buffer, j+1, k));
> i = k + 1;
> }
> return map;
> }
> 
> fn search<'b>(letters : &[u8], dictionary : &'b HashMap<&'b [u8],&'b [u8]>) 
> -> ~HashSet<&'b [u8]>
> {
> let mut set = ~HashSet::new();
> for uint::range(2, letters.len() + 1) |i| {
> let mut key = MapKey(vec::from_elem(i, 0));
> // pub fn each_combination(values : &[T], r : uint, fun : 
> &fn(combo : &[T]) -> bool) -> bool
> for each_combination(letters,i) |combo| {
> for combo.eachi |j,&ch| { key[j] = ch; }
> {
> match dictionary.find_equiv(&key) {
> Some(val) => {
> set.insert(*val);
> }
> None => { }
> }
> }
> }
> }
> return set;
> }
> 
> fn main() {
> let args = os::args();
> if args.len() < 2 {
> fail!(~"Usage: anagrams letters");
> }
> let letters = get_letters(args[1]);
> do with_mmap_file_contents("anadict-rust.txt") |buf| {
> let map = line_map(buf);
> let set = search(letters, map);
> // Just count them for now...
> let mut count = 0;
> for set.each |ln| {
> count += 1 + vec::count(*ln, &(' ' as u8));
> }
> println(fmt!("%?", count));
> }
> }
> ```
> 
> 
> Niko
> 
> On Thu, May 30, 2013 at 09:00:32AM -0500, Tommy M. McGuire wrote:
> > On 05/30/2013 05:09 AM, Niko Matsakis wrote:
> > > On Wed, May 29, 2013 at 04:55:31PM -0500, Tommy M. McGuire wrote:
> > >> The problem is that I want to use a completely unrelated vector as the
> > >> argument to find() instead of an alias for part of the buffer or a pair
> > >> of indices into the buffer.
> > >>
> > >> Currently, with my quick change to incoming, the code
> > >>
> > >> let kkey : &[u8] = key;   // key : ~[u8]
> > >> match dictionary.find(&kkey) {
> > >>
> > >> produces:
> > >>
> > >> 55:38 error: borrowed value does not live long enough
> > >> let kkey : &[u8] = key;
> > >>^~~
> > >> 67:1 note: borrowed pointer must be valid for the lifetime
> > >> &br_named({repr: 83, ctxt: 0})  as defined on the block at 48:0...
> > >> ...
> > >> 65:5 note: ...but borrowed value is only valid for

Re: [rust-dev] Question about lifetimes in type parameters

2013-06-01 Thread Niko Matsakis
OK, I finally got a chance to take a look. Indeed, this is not a bug,
I just misunderstood what was going on. The problem is that the key is
`&'b [u8]` but you can't supply precisely that type, because the key
you are using to do th elookup has a shorter lifetime. This is true and
the type checker is right to complain.

What you want is to do in these situations is to use the `find_equiv`
method, which demands a key that is not necessarily the *same* type as
what is in the map but just one comparable to it. Unfortunately, we
don't have an equivalence for two slices of unequal lifetimes right
now (and we can't right one at the moment due to some limitations that
I am supposed to be lifting). Annoyingly, we also don't have an
equivalence from ~[u8] to &[u8], only in the reverse direction. We
should fix this, but usually people have ~[u8] as the key and &[u8] as
the equivalent lookup key, not the other way around.

However, you can workaround this limitation using a "new type" struct.
Here is a version that works. The main trick is to add a temporary
type `MapKey` for which we can define the `Equiv` trait so that it can
be compared to the slices that are in your table.


```
extern mod extra;
use std::vec;
use std::hashmap::*;
use std::os;
use std::str;
use std::uint;
use std::cmp::eq;

#[deriving(IterBytes)]
struct MapKey(~[u8]);
impl<'self> Equiv<&'self [u8]> for MapKey {
fn equiv(&self, other: & &'self [u8]) -> bool {
let slice1: &[u8] = **self;
let slice2: &[u8] = *other;
slice1 == slice2
}
}

pub fn with_mmap_file_contents(filename : &str, f : &fn(v : &[u8]) -> U) -> 
U {
fail!()
}

pub fn each_combination(values : &[T], r : uint, fun : &fn(combo : 
&[T]) -> bool) -> bool {
fail!()
}

fn get_letters(s : &str) -> ~[u8] {
let mut t = str::to_chars(s);
extra::sort::quick_sort(t, |a,b| *a <= *b);
return vec::from_fn(t.len(), |i| t[i] as u8);
}

fn line_map<'b>(buffer : &'b [u8]) -> ~HashMap<&'b [u8],&'b [u8]> {
let length = buffer.len();
let mut map = ~HashMap::new();
let mut i = 0;
while i < length {
let mut j = i;
while j < length && buffer[j] != ' ' as u8 { j += 1; }
let mut k = j+1;
while k < length && buffer[k] != '\n' as u8 { k += 1; }
map.insert(vec::slice(buffer, i, j), vec::slice(buffer, j+1, k));
i = k + 1;
}
return map;
}

fn search<'b>(letters : &[u8], dictionary : &'b HashMap<&'b [u8],&'b [u8]>) -> 
~HashSet<&'b [u8]>
{
let mut set = ~HashSet::new();
for uint::range(2, letters.len() + 1) |i| {
let mut key = MapKey(vec::from_elem(i, 0));
// pub fn each_combination(values : &[T], r : uint, fun : 
&fn(combo : &[T]) -> bool) -> bool
for each_combination(letters,i) |combo| {
for combo.eachi |j,&ch| { key[j] = ch; }
{
match dictionary.find_equiv(&key) {
Some(val) => {
set.insert(*val);
}
None => { }
}
}
}
}
return set;
}

fn main() {
let args = os::args();
if args.len() < 2 {
fail!(~"Usage: anagrams letters");
}
let letters = get_letters(args[1]);
do with_mmap_file_contents("anadict-rust.txt") |buf| {
let map = line_map(buf);
let set = search(letters, map);
// Just count them for now...
let mut count = 0;
for set.each |ln| {
count += 1 + vec::count(*ln, &(' ' as u8));
}
println(fmt!("%?", count));
}
}
```


Niko

On Thu, May 30, 2013 at 09:00:32AM -0500, Tommy M. McGuire wrote:
> On 05/30/2013 05:09 AM, Niko Matsakis wrote:
> > On Wed, May 29, 2013 at 04:55:31PM -0500, Tommy M. McGuire wrote:
> >> The problem is that I want to use a completely unrelated vector as the
> >> argument to find() instead of an alias for part of the buffer or a pair
> >> of indices into the buffer.
> >>
> >> Currently, with my quick change to incoming, the code
> >>
> >> let kkey : &[u8] = key;   // key : ~[u8]
> >> match dictionary.find(&kkey) {
> >>
> >> produces:
> >>
> >> 55:38 error: borrowed value does not live long enough
> >> let kkey : &[u8] = key;
> >>^~~
> >> 67:1 note: borrowed pointer must be valid for the lifetime
> >> &br_named({repr: 83, ctxt: 0})  as defined on the block at 48:0...
> >> ...
> >> 65:5 note: ...but borrowed value is only valid for the block at 50:46
> >>
> >> The lifetime '&br_named(...)' stuff should be "'b", the lifetime
> >> parameter of the function (the block at 48:0) that is associated with
> >> the keys and values from the HashMap (was LinearMap) and the buffer.
> > 
> > This seems like a bug (also, what a lousy error message! sorry.), I
> > will further investigate.
> 
> Thanks! (The error message changed when I updated incoming, so it's
> something recent.)
> 
> I'm not sure it is a bug, th

Re: [rust-dev] Scheduler and I/O work items for the summer

2013-06-01 Thread Vadim
On Fri, May 31, 2013 at 3:45 PM, Brian Anderson wrote:

>
> With this problem in general I think the obvious solutions amount to
> taking one of two approaches: translate I/O events into pipe events;
> translate pipe events into I/O events. Solving the problem efficiently for
> either one is rather simpler than solving both. The example you show is
> promising model that looks like it could naively be implemented by
> buffering I/O into pipes. bblum and I talked about an implementation that
> would work well for this approach, but it has costs. I imagine it working
> like this.
>
> 1) The resolve_xxx function partitions the elements into pipesy types and
> I/O types.
> 3) For each of the I/O types it creates a new pipe, and registers a uv
> event. Note that because of I/O-scheduler affinity some of these may cause
> the task to migrate between threads.
> 4) Now we just wait on all the pipes.
>

What if futures were treated as one-shot pipes with one element queue
capacity, and "real" pipes were used only when there's a need for
buffering?  That would help to reduce per-operation costs (also see notes
below about allocation).


>
> I think we would want to do this too for efficiency reasons. The above
> outline has two major costs: the first is the extra pipes and the second is
> the buffering of the I/O. For example, the synchronous read method looks
> like `read(buf: &mut [u8])` where the buf is typically allocated on the
> stack. In the future scenario presumably it would be more like `read() ->
> Future<~[u8]>`, forcing a heap allocation, but maybe `read(buf: &mut [u8])
> -> Future<&mut [u8]>` is workable.
>

Not necessarily.  In fact, .NET's signature of the read method is something
like this: fn read(buf: &mut [u8]) -> ~Future;  It returns just the
read bytes count.  This is perfectly fine for simple usage because caller
still has a reference to the buffer.

Now, if you want to send it over to another task, this is indeed a problem,
however composition of future comes to the rescue.   Each .NET's future has
a method that allows to attach a continuation that yields a new future of
the type of continuation's result:

trait Future
{
fn continue_with(&self, cont: fn (T) -> T1) -> Future;
}

let buf = ~[0,..1024];
let f1 = stream.read(&buf);
let f2 : Future<(~[u8],int> = f1.continue_with(|read| return (buf, read));

Now f2 contains all information needed to process received data in another
task.


>
>2. Each i/o operation now needs to allocate heap memory for the future
> object.   This has been known to create GC performance problems for .NET
> web apps which process large numbers of small requests.  If these can live
> on the stack, though, maybe this wouldn't be a problem for Rust.
>
>
> Haha, yep that's a concern.
>

I know that Rust currently doesn't currently support this, but what if
futures could use a custom allocator?   Then it could work like this:

1. Futures use a custom free-list allocator for performance.
2. The I/O request allocates new future object, registers uv event, then
returns unique pointer to the future to its' caller.  However I/O manager
retains internal reference to the future, so that it can be resolved once
I/O completes.
3. The future object also has a flag indicating that there's an outstanding
I/O, so if caller drops the reference to it, it won't be returned to the
free list until I/O completes.
4. When I/O is complete, the future get resolved and all attached
continuations are run.


Vadim
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev