move hashmap to its own module for now

pull/3182/head
Alexander Medvednikov 2019-12-22 00:38:43 +03:00
parent 4fc8842edb
commit 2b9392c46c
4 changed files with 41 additions and 39 deletions

View File

@ -36,7 +36,7 @@ TCCREPO := https://github.com/vlang/tccbin_win
VCFILE := v_win.c VCFILE := v_win.c
endif endif
all: latest_vc latest_tcc all: latest_vc
ifdef WIN32 ifdef WIN32
$(CC) -std=c99 -w -o v0.exe $(TMPVC)/$(VCFILE) $(LDFLAGS) $(CC) -std=c99 -w -o v0.exe $(TMPVC)/$(VCFILE) $(LDFLAGS)
./v0.exe -o v.exe v.v ./v0.exe -o v.exe v.v
@ -45,7 +45,7 @@ else
$(CC) -std=gnu11 -w -o v $(TMPVC)/$(VCFILE) $(LDFLAGS) -lm $(CC) -std=gnu11 -w -o v $(TMPVC)/$(VCFILE) $(LDFLAGS) -lm
ifdef ANDROID ifdef ANDROID
chmod 755 v chmod 755 v
endif endif
@(VC_V=`./v version | cut -f 3 -d " "`; \ @(VC_V=`./v version | cut -f 3 -d " "`; \
V_V=`git rev-parse --short HEAD`; \ V_V=`git rev-parse --short HEAD`; \
if [ $$VC_V != $$V_V ]; then \ if [ $$VC_V != $$V_V ]; then \
@ -54,7 +54,7 @@ endif
fi) fi)
ifndef ANDROID ifndef ANDROID
$(MAKE) modules $(MAKE) modules
endif endif
endif endif
@echo "V has been successfully built" @echo "V has been successfully built"
@ -70,19 +70,19 @@ fresh_vc:
rm -rf $(TMPVC) rm -rf $(TMPVC)
$(GITFASTCLONE) $(VCREPO) $(TMPVC) $(GITFASTCLONE) $(VCREPO) $(TMPVC)
latest_tcc: $(TMPTCC)/.git/config #latest_tcc: $(TMPTCC)/.git/config
ifndef ANDROID #ifndef ANDROID
cd $(TMPTCC) && $(GITCLEANPULL) #cd $(TMPTCC) && $(GITCLEANPULL)
endif #endif
fresh_tcc: #fresh_tcc:
ifndef ANDROID #ifndef ANDROID
rm -rf $(TMPTCC) #rm -rf $(TMPTCC)
$(GITFASTCLONE) $(TCCREPO) $(TMPTCC) #$(GITFASTCLONE) $(TCCREPO) $(TMPTCC)
endif #endif
$(TMPTCC)/.git/config: #$(TMPTCC)/.git/config:
$(MAKE) fresh_tcc #$(MAKE) fresh_tcc
$(TMPVC)/.git/config: $(TMPVC)/.git/config:
$(MAKE) fresh_vc $(MAKE) fresh_vc
@ -93,7 +93,7 @@ selfcompile:
modules: module_builtin module_strings module_strconv modules: module_builtin module_strings module_strconv
module_builtin: module_builtin:
./v build module vlib/builtin > /dev/null ./v build module vlib/builtin > /dev/null
module_strings: module_strings:
./v build module vlib/strings > /dev/null ./v build module vlib/strings > /dev/null
module_strconv: module_strconv:
./v build module vlib/strconv > /dev/null ./v build module vlib/strconv > /dev/null

View File

@ -1,31 +1,32 @@
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved. // Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license // Use of this source code is governed by an MIT license
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module builtin module hashmap
/* /*
This is work in progress. This is work in progress.
A very early test version of the hashmap with a fixed size. A very early test version of the Hashmap with a fixed size.
Only works with string keys and int values for now. Only works with string keys and int values for now.
I added this to improve performance of the V compiler, I added this to improve performance of the V compiler,
which uses lots of O(log n) map get's. Turned out with N < 10 000 which uses lots of O(log n) map get's. Turned out with N < 10 000
the performance gains are basically non-existent. the performance gains are basically non-existent.
*/ */
struct hashmap { struct Hashmap {
cap int cap int
keys []string keys []string
table []hashmapentry table []Hashmapentry
elm_size int elm_size int
pub: pub mut:
nr_collisions int nr_collisions int
} }
struct hashmapentry { struct Hashmapentry {
mut:
key string key string
val int val int
next &hashmapentry // linked list for collisions next &Hashmapentry // linked list for collisions
} }
const ( const (
@ -35,7 +36,7 @@ const (
const( const(
fnv64_prime = 1099511628211 fnv64_prime = 1099511628211
fnv64_offset_basis = 14695981039346656037 fnv64_offset_basis = u64(14695981039346656037)
) )
const( const(
@ -43,7 +44,7 @@ const(
fnv32_prime = u32(16777619) fnv32_prime = u32(16777619)
) )
pub fn new_hashmap(planned_nr_items int) hashmap { pub fn new_hashmap(planned_nr_items int) Hashmap {
mut cap := planned_nr_items * 5 mut cap := planned_nr_items * 5
if cap < min_cap { if cap < min_cap {
cap = min_cap cap = min_cap
@ -51,14 +52,14 @@ pub fn new_hashmap(planned_nr_items int) hashmap {
if cap > max_cap { if cap > max_cap {
cap = max_cap cap = max_cap
} }
return hashmap{ return Hashmap{
cap: cap cap: cap
elm_size: 4 elm_size: 4
table: make(cap, cap, sizeof(hashmapentry)) table: make(cap, cap, sizeof(Hashmapentry))
} }
} }
pub fn (m mut hashmap) set(key string, val int) { pub fn (m mut Hashmap) set(key string, val int) {
// mut hash := int(b_fabs(key.hash())) // mut hash := int(b_fabs(key.hash()))
// idx := hash % m.cap // idx := hash % m.cap
idx := int(fnv1a32(key) % m.cap) idx := int(fnv1a32(key) % m.cap)
@ -70,16 +71,16 @@ pub fn (m mut hashmap) set(key string, val int) {
for e.next != 0 { for e.next != 0 {
e = e.next e = e.next
} }
e.next = &hashmapentry{ e.next = &Hashmapentry{
key,val,0} key,val,0}
} }
else { else {
m.table[idx] = hashmapentry{ m.table[idx] = Hashmapentry{
key,val,0} key,val,0}
} }
} }
pub fn (m mut hashmap) get(key string) int { pub fn (m &Hashmap) get(key string) int {
// mut hash := int(b_fabs(key.hash())) // mut hash := int(b_fabs(key.hash()))
// idx := hash % m.cap // idx := hash % m.cap
idx := int(fnv1a32(key) % m.cap) idx := int(fnv1a32(key) % m.cap)

View File

@ -1,3 +1,5 @@
module hashmap
import rand import rand
fn test_random_strings() { fn test_random_strings() {
@ -15,7 +17,7 @@ fn test_random_strings() {
m.set('foo', 12) m.set('foo', 12)
val := m.get('foo') val := m.get('foo')
assert val == 12 assert val == 12
} }
fn test_large_hashmap() { fn test_large_hashmap() {
N := 300 * 1000 N := 300 * 1000
@ -29,4 +31,4 @@ fn test_large_hashmap() {
key := i.str() key := i.str()
assert nums.get(key) == i assert nums.get(key) == i
} }
} }

View File

@ -156,14 +156,14 @@ pub fn (v &V) finalize_compilation() {
pub fn (v mut V) add_parser(parser Parser) int { pub fn (v mut V) add_parser(parser Parser) int {
pidx := v.parsers.len pidx := v.parsers.len
v.parsers << parser v.parsers << parser
file_path := if filepath.is_abs(parser.file_path) { file_path := if filepath.is_abs(parser.file_path) {
parser.file_path } else { os.realpath(parser.file_path) } parser.file_path } else { os.realpath(parser.file_path) }
v.file_parser_idx[file_path] = pidx v.file_parser_idx[file_path] = pidx
return pidx return pidx
} }
pub fn (v &V) get_file_parser_index(file string) ?int { pub fn (v &V) get_file_parser_index(file string) ?int {
file_path := if filepath.is_abs(file) { file_path := if filepath.is_abs(file) {
file } else { os.realpath(file) } file } else { os.realpath(file) }
if file_path in v.file_parser_idx { if file_path in v.file_parser_idx {
return v.file_parser_idx[file_path] return v.file_parser_idx[file_path]
@ -1058,7 +1058,7 @@ pub fn new_v(args []string) &V {
is_live: '-live' in args is_live: '-live' in args
sanitize: '-sanitize' in args sanitize: '-sanitize' in args
// nofmt: '-nofmt' in args // nofmt: '-nofmt' in args
show_c_cmd: '-show_c_cmd' in args show_c_cmd: '-show_c_cmd' in args
translated: 'translated' in args translated: 'translated' in args
is_run: 'run' in args is_run: 'run' in args
@ -1077,7 +1077,7 @@ pub fn new_v(args []string) &V {
building_v: !is_repl && (rdir_name == 'compiler' || rdir_name == 'v.v' || dir.contains('vlib')) building_v: !is_repl && (rdir_name == 'compiler' || rdir_name == 'v.v' || dir.contains('vlib'))
comptime_define: comptime_define comptime_define: comptime_define
// is_fmt: comptime_define == 'vfmt' // is_fmt: comptime_define == 'vfmt'
user_mod_path: user_mod_path user_mod_path: user_mod_path
vlib_path: vlib_path vlib_path: vlib_path
vpath: vpath vpath: vpath
@ -1145,7 +1145,6 @@ pub fn vfmt(args []string) {
println('v fmt can only be used on .v files') println('v fmt can only be used on .v files')
exit(1) exit(1)
} }
println('WIP')
vexe := vexe_path() vexe := vexe_path()
// launch_tool('vfmt', '-d vfmt') // launch_tool('vfmt', '-d vfmt')
vroot := os.dir(vexe) vroot := os.dir(vexe)