implement a map testing benchmark
This involved some other changes: - add a managed<T> wrapper that makes send_map usable from @-data - implement map<K,V> for managed<send_map> Unit tests are coming.
This commit is contained in:
@@ -55,6 +55,7 @@ export hash;
|
||||
export cmp;
|
||||
export num;
|
||||
export path;
|
||||
export managed;
|
||||
|
||||
// NDM seems to be necessary for resolve to work
|
||||
export option_iter;
|
||||
@@ -261,6 +262,7 @@ mod sys;
|
||||
#[warn(non_camel_case_types)]
|
||||
mod unsafe;
|
||||
|
||||
mod managed;
|
||||
|
||||
// Modules supporting compiler-generated code
|
||||
// Exported but not part of the public interface
|
||||
|
||||
62
src/libcore/managed.rs
Normal file
62
src/libcore/managed.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
/*!
|
||||
|
||||
Module for wrapping freezable data structures in managed boxes.
|
||||
Normally freezable data structures require an unaliased reference,
|
||||
such as `T` or `~T`, so that the compiler can track when they are
|
||||
being mutated. The `rw<T>` type converts these static checks into
|
||||
dynamic checks: your program will fail if you attempt to perform
|
||||
mutation when the data structure should be immutable.
|
||||
|
||||
*/
|
||||
|
||||
#[forbid(non_camel_case_types)];
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
import util::with;
|
||||
import unsafe::transmute_immut;
|
||||
|
||||
export Managed;
|
||||
|
||||
enum Mode { ReadOnly, Mutable, Immutable }
|
||||
|
||||
struct Data<T> {
|
||||
mut value: T;
|
||||
mut mode: Mode;
|
||||
}
|
||||
|
||||
type Managed<T> = @Data<T>;
|
||||
|
||||
fn Managed<T>(+t: T) -> Managed<T> {
|
||||
@Data {value: t, mode: ReadOnly}
|
||||
}
|
||||
|
||||
impl<T> Data<T> {
|
||||
fn borrow_mut<R>(op: &fn(t: &mut T) -> R) -> R {
|
||||
match self.mode {
|
||||
Immutable => fail fmt!("%? currently immutable",
|
||||
self.value),
|
||||
ReadOnly | Mutable => {}
|
||||
}
|
||||
|
||||
do with(&mut self.mode, Mutable) {
|
||||
op(&mut self.value)
|
||||
}
|
||||
}
|
||||
|
||||
fn borrow_const<R>(op: &fn(t: &const T) -> R) -> R {
|
||||
op(&const self.value)
|
||||
}
|
||||
|
||||
fn borrow_imm<R>(op: &fn(t: &T) -> R) -> R {
|
||||
match self.mode {
|
||||
Mutable => fail fmt!("%? currently mutable",
|
||||
self.value),
|
||||
ReadOnly | Immutable => {}
|
||||
}
|
||||
|
||||
do with(&mut self.mode, Immutable) {
|
||||
op(unsafe{transmute_immut(&mut self.value)})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,6 +221,13 @@ mod linear {
|
||||
self.size -= 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
fn clear() {
|
||||
for uint::range(0, self.buckets.len()) |idx| {
|
||||
self.buckets[idx] = none;
|
||||
}
|
||||
self.size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
priv impl<K,V> &LinearMap<K,V> {
|
||||
|
||||
@@ -12,6 +12,24 @@ pure fn id<T>(+x: T) -> T { x }
|
||||
/// Ignores a value.
|
||||
pure fn ignore<T>(+_x: T) { }
|
||||
|
||||
/// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the
|
||||
/// original value of `*ptr`.
|
||||
#[inline(always)]
|
||||
fn with<T: copy, R>(
|
||||
ptr: &mut T,
|
||||
+new_value: T,
|
||||
op: &fn() -> R) -> R
|
||||
{
|
||||
// NDM: if swap operator were defined somewhat differently,
|
||||
// we wouldn't need to copy...
|
||||
|
||||
let old_value = *ptr;
|
||||
*ptr = move new_value;
|
||||
let result = op();
|
||||
*ptr = move old_value;
|
||||
return move result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap the values at two mutable locations of the same type, without
|
||||
* deinitialising or copying either one.
|
||||
|
||||
Reference in New Issue
Block a user