mirror of
https://github.com/golang/go
synced 2024-11-23 14:20:05 -07:00
runtime: use better hash for non-empty interface
The implementation 'return 0' results in too many collisions. LGTM=khr R=golang-codereviews, adonovan, khr CC=golang-codereviews, iant, khr, r https://golang.org/cl/125720044
This commit is contained in:
parent
2185dbcd85
commit
f098a29630
@ -111,7 +111,22 @@ func nohash(a unsafe.Pointer, s uintptr, h uintptr) uintptr {
|
||||
func interhash(a *interface {
|
||||
f()
|
||||
}, s uintptr, h uintptr) uintptr {
|
||||
return 0
|
||||
tab := (*iface)(unsafe.Pointer(a)).tab
|
||||
if tab == nil {
|
||||
return h
|
||||
}
|
||||
t := tab._type
|
||||
fn := goalg(t.alg).hash
|
||||
if **(**uintptr)(unsafe.Pointer(&fn)) == nohashcode {
|
||||
// calling nohash will panic too,
|
||||
// but we can print a better error.
|
||||
panic(errorString("hash of unhashable type " + *t._string))
|
||||
}
|
||||
if uintptr(t.size) <= ptrSize {
|
||||
return c1 * fn(unsafe.Pointer(&(*eface)(unsafe.Pointer(a)).data), uintptr(t.size), h^c0)
|
||||
} else {
|
||||
return c1 * fn((*eface)(unsafe.Pointer(a)).data, uintptr(t.size), h^c0)
|
||||
}
|
||||
}
|
||||
|
||||
func nilinterhash(a *interface{}, s uintptr, h uintptr) uintptr {
|
||||
|
@ -475,44 +475,6 @@ func assertE2E2(inter *InterfaceType, e Eface) (ret Eface, ok bool) {
|
||||
ok = e.type != nil;
|
||||
}
|
||||
|
||||
static uintptr
|
||||
ifacehash1(void *data, Type *t, uintptr h)
|
||||
{
|
||||
Alg *alg;
|
||||
uintptr size;
|
||||
Eface err;
|
||||
|
||||
if(t == nil)
|
||||
return 0;
|
||||
|
||||
alg = t->alg;
|
||||
size = t->size;
|
||||
if(alg->hash->fn == (void(*)())runtime·nohash) {
|
||||
// calling nohash will panic too,
|
||||
// but we can print a better error.
|
||||
runtime·newErrorString(runtime·catstring(runtime·gostringnocopy((byte*)"hash of unhashable type "), *t->string), &err);
|
||||
runtime·panic(err);
|
||||
}
|
||||
if(size <= sizeof(data))
|
||||
return ((uintptr(*)(void**,uintptr,uintptr))alg->hash)(&data, size, h);
|
||||
else
|
||||
return ((uintptr(*)(void*,uintptr,uintptr))alg->hash)(data, size, h);
|
||||
}
|
||||
|
||||
uintptr
|
||||
runtime·ifacehash(Iface a, uintptr h)
|
||||
{
|
||||
if(a.tab == nil)
|
||||
return h;
|
||||
return ifacehash1(a.data, a.tab->type, h);
|
||||
}
|
||||
|
||||
uintptr
|
||||
runtime·efacehash(Eface a, uintptr h)
|
||||
{
|
||||
return ifacehash1(a.data, a.type, h);
|
||||
}
|
||||
|
||||
static bool
|
||||
ifaceeq1(void *data1, void *data2, Type *t)
|
||||
{
|
||||
|
@ -651,19 +651,19 @@ enum {
|
||||
};
|
||||
void runtime·hashinit(void);
|
||||
|
||||
uintptr runtime·memhash(void*, uintptr, uintptr);
|
||||
uintptr runtime·nohash(void*, uintptr, uintptr);
|
||||
uintptr runtime·strhash(void*, uintptr, uintptr);
|
||||
uintptr runtime·interhash(void*, uintptr, uintptr);
|
||||
uintptr runtime·nilinterhash(void*, uintptr, uintptr);
|
||||
uintptr runtime·f32hash(void*, uintptr, uintptr);
|
||||
uintptr runtime·f64hash(void*, uintptr, uintptr);
|
||||
uintptr runtime·c64hash(void*, uintptr, uintptr);
|
||||
uintptr runtime·c128hash(void*, uintptr, uintptr);
|
||||
uintptr runtime·aeshash(void*, uintptr, uintptr);
|
||||
uintptr runtime·aeshash32(void*, uintptr, uintptr);
|
||||
uintptr runtime·aeshash64(void*, uintptr, uintptr);
|
||||
uintptr runtime·aeshashstr(void*, uintptr, uintptr);
|
||||
void runtime·memhash(void*, uintptr, uintptr, uintptr);
|
||||
void runtime·nohash(void*, uintptr, uintptr, uintptr);
|
||||
void runtime·strhash(void*, uintptr, uintptr, uintptr);
|
||||
void runtime·interhash(void*, uintptr, uintptr, uintptr);
|
||||
void runtime·nilinterhash(void*, uintptr, uintptr, uintptr);
|
||||
void runtime·f32hash(void*, uintptr, uintptr, uintptr);
|
||||
void runtime·f64hash(void*, uintptr, uintptr, uintptr);
|
||||
void runtime·c64hash(void*, uintptr, uintptr, uintptr);
|
||||
void runtime·c128hash(void*, uintptr, uintptr, uintptr);
|
||||
void runtime·aeshash(void*, uintptr, uintptr, uintptr);
|
||||
void runtime·aeshash32(void*, uintptr, uintptr, uintptr);
|
||||
void runtime·aeshash64(void*, uintptr, uintptr, uintptr);
|
||||
void runtime·aeshashstr(void*, uintptr, uintptr, uintptr);
|
||||
|
||||
void runtime·memequal(bool*, uintptr, void*, void*);
|
||||
void runtime·noequal(bool*, uintptr, void*, void*);
|
||||
@ -876,8 +876,6 @@ void runtime·mallocinit(void);
|
||||
void runtime·chaninit(void);
|
||||
bool runtime·ifaceeq_c(Iface, Iface);
|
||||
bool runtime·efaceeq_c(Eface, Eface);
|
||||
uintptr runtime·ifacehash(Iface, uintptr);
|
||||
uintptr runtime·efacehash(Eface, uintptr);
|
||||
void* runtime·malloc(uintptr size);
|
||||
void runtime·runpanic(Panic*);
|
||||
uintptr runtime·getcallersp(void*);
|
||||
|
Loading…
Reference in New Issue
Block a user