move hashmap to its own module for now
parent
4fc8842edb
commit
2b9392c46c
32
Makefile
32
Makefile
|
@ -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
|
||||||
|
|
|
@ -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)
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue