std: map 을 쓴다 -- 바이트 열에서 값으로
컴파일러는 이름을 끊임없이 찾는데 리스트 선형 탐색은 그 모양이 아니다. 키는 맵이 소유하는 한 버퍼에 복사되고 슬롯은 그 안의 어디인지만 적는다 -- R11 이 말하는 아레나와 핸들 모양이고, 그래서 맵을 놓는 것이 엔트리마다 하나가 아니라 두 번의 해제다. 개방 주소법에 선형 탐사. 표는 2의 거듭제곱이라 나눗셈이 아니라 마스크이고, 탐사가 길어지는 것이 표가 차는 것보다 먼저라 3/4 에서 자란다. 길에서 고친 것 넷: - 인스턴스를 만들 때 선언 유닛으로 전환하지 않아서, 필드 타입 Slot(V) 를 호출자 유닛에서 찾고 있었다. - mem.alloc_slice 가 원소 타입으로 단순한 이름만 받았다. Slot(V) 같은 인스턴스도 받는다. - 쓸 수 있는지를 바인딩이 아니라 소유된 것이 정한다. let p: ^[]mut T 는 p 를 고정하고 그것이 소유한 것은 쓸 수 있게 둔다. 슬라이스 인덱스도 마찬가지다. - 메서드 인자에 자유 함수와 같은 호출 한정 약화가 없었다. 알게 된 것: 대여는 루트 단위라 self 의 한 필드에 쓰는 동안 다른 필드를 읽을 수 없다. 지역으로 빼거나 메서드를 나누면 되지만, 필드 단위 대여가 있으면 훨씬 편할 자리다. count 5 / fn 2 let 3 missing 0 / grown 64 / after 40 / balanced 218/218, 28/28.
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
// EXIT:0
|
||||
// OUTPUT:count 5
|
||||
// OUTPUT:fn 2 let 3 missing 0
|
||||
// OUTPUT:grown 64
|
||||
// OUTPUT:after 40
|
||||
// OUTPUT:balanced
|
||||
unit maps;
|
||||
import std.io;
|
||||
import std.map;
|
||||
import std.fmt;
|
||||
import std.sys;
|
||||
|
||||
fn run() -> !void {
|
||||
var seen: map.Map(i32) = try map.Map(i32).with_capacity(4);
|
||||
try seen.put("unit", 1);
|
||||
try seen.put("fn", 2);
|
||||
try seen.put("let", 3);
|
||||
try seen.put("struct", 4);
|
||||
try seen.put("return", 5);
|
||||
@print("count {}\n", seen.count_of());
|
||||
@print("fn {} let {} missing {}\n", seen.get("fn", 0), seen.get("let", 0),
|
||||
seen.get("nope", 0));
|
||||
// Enough keys to make it grow more than once.
|
||||
var buf: [8]u8 = undefined;
|
||||
var i: usize = 0;
|
||||
while i < 40 {
|
||||
let n: usize = fmt.fmt_i32(buf[..], i as i32);
|
||||
try seen.put(buf[0..n], (i as i32) + 100);
|
||||
i = i + 1;
|
||||
}
|
||||
@print("grown {}\n", seen.room());
|
||||
var found: usize = 0;
|
||||
i = 0;
|
||||
while i < 40 {
|
||||
let n: usize = fmt.fmt_i32(buf[..], i as i32);
|
||||
if seen.get(buf[0..n], 0) == (i as i32) + 100 { found = found + 1; }
|
||||
i = i + 1;
|
||||
}
|
||||
@print("after {}\n", found);
|
||||
return;
|
||||
}
|
||||
|
||||
fn main() -> i32 {
|
||||
run() catch |e| { @print("failed\n"); return 1; };
|
||||
if sys.allocs() != sys.frees() { @print("leaked\n"); return 2; }
|
||||
@print("balanced\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user