Skip to content

Commit

Permalink
Fixing memory issues
Browse files Browse the repository at this point in the history
  • Loading branch information
object88 committed Jan 9, 2017
1 parent f624ef7 commit 203707c
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 146 deletions.
21 changes: 10 additions & 11 deletions hashmap.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package immutable

import (
"fmt"
"math"
"math/rand"
"time"
Expand Down Expand Up @@ -63,19 +62,19 @@ func (h *HashMap) Get(key Key) Value {

totalEntries := uint64(b.entryCount)

fmt.Printf("\nlobSize: %d; h.lobMask: 0x%016x\n", h.lobSize, h.lobMask)
fmt.Printf("hashKey: 0x%016x / selectedBucket: %d / mashedHash: 0x%016x\n", hashkey, selectedBucket, maskedHash)
// fmt.Printf("\nlobSize: %d; h.lobMask: 0x%016x\n", h.lobSize, h.lobMask)
// fmt.Printf("hashKey: 0x%016x / selectedBucket: %d / mashedHash: 0x%016x\n", hashkey, selectedBucket, maskedHash)

for b != nil {
fmt.Printf(" entryCount: %d\n", b.entryCount)
fmt.Printf(" entries: [\n")
for i := uint64(0); i < uint64(b.entryCount); i++ {
fmt.Printf(" [0x%016x,%s] -> %s\n", b.hobs.Read(i), b.entries[i].key, b.entries[i].value)
}
fmt.Printf(" ]\n")
// fmt.Printf(" entryCount: %d\n", b.entryCount)
// fmt.Printf(" entries: [\n")
// for i := uint64(0); i < uint64(b.entryCount); i++ {
// fmt.Printf(" [0x%016x,%s] -> %s\n", b.hobs.Read(i), b.entries[i].key, b.entries[i].value)
// }
// fmt.Printf(" ]\n")

for index := uint64(0); index < totalEntries; index++ {
fmt.Printf("0x%016x <-> 0x%016x :: %s <-> %s\n", b.hobs.Read(index), maskedHash, b.entries[index].key, key)
// fmt.Printf("0x%016x <-> 0x%016x :: %s <-> %s\n", b.hobs.Read(index), maskedHash, b.entries[index].key, key)
if b.hobs.Read(index) == maskedHash && b.entries[index].key == key {
return b.entries[index].value
}
Expand Down Expand Up @@ -261,7 +260,7 @@ func createHashMap(size int, options *HashMapOptions) *HashMap {
lobMask := uint32(^(0xffffffff << lobSize))
buckets := make([]*bucket, initialSize)

fmt.Printf("lobSize: %d; lobMask: 0x%032b\n", lobSize, lobMask)
// fmt.Printf("lobSize: %d; lobMask: 0x%032b\n", lobSize, lobMask)

src := rand.NewSource(time.Now().UnixNano())
random := rand.New(src)
Expand Down
73 changes: 35 additions & 38 deletions memory/memory32.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package memory

import "fmt"

const fullBlock = ^uint32(0)

// Memories32 is all your memories.
Expand All @@ -12,45 +10,46 @@ type Memories32 struct {

// Assign sets a value to the internal memory at the given index
func (m *Memories32) Assign(index uint64, value uint64) {
bitsRemaining := uint64(m.bitsPerEntry)
offset := bitsRemaining * index
bitsRemaining := m.bitsPerEntry
offset := bitsRemaining * uint32(index)
byteOffset := offset / bitsInLargeBlock
bitOffset := offset % bitsInLargeBlock

fmt.Printf("\nAssigning %032b to index %d\n", value, index)
fmt.Printf("byteOffset: %d, bitOffset: %d, bitsRemaining: %d\n", byteOffset, bitOffset, bitsRemaining)
// fmt.Printf("\nAssigning %064b to index %d\n", value, index)

writeBitCount := bitsInLargeBlock - bitOffset
if writeBitCount > bitsRemaining {
writeBitCount = bitsRemaining
}
initial := uint64(m.m[byteOffset])
mask := uint64(fullBlock << writeBitCount)
result := (initial & ^(^mask << bitOffset)) | ((value & ^mask) << bitOffset)
m.m[byteOffset] = uint32(result)
// fmt.Printf("byteOffset: %d, bitOffset: %d, bitsRemaining: %d, writeBitCount: %d\n", byteOffset, bitOffset, bitsRemaining, writeBitCount)
initial := m.m[byteOffset]
mask := ^(fullExtraLargeBlock << writeBitCount)
result := uint32(value&mask)<<bitOffset | initial&^((^(fullBlock << writeBitCount))<<bitOffset)
m.m[byteOffset] = result

fmt.Printf("result at %d: %032b\n", byteOffset, m.m[byteOffset])
// fmt.Printf("result at %d: %032b -> %032b\n", byteOffset, initial, result)

bitsRemaining -= writeBitCount
byteOffset++

if bitsRemaining > 32 {
o := (uint64(m.bitsPerEntry) - bitsRemaining)
result := ((value & (uint64(fullBlock) << o)) >> o)
m.m[byteOffset] = uint32(result)
fmt.Printf("result at %d: %032b\n", byteOffset, m.m[byteOffset])
if bitsRemaining >= 32 {
o := m.bitsPerEntry - bitsRemaining
result := uint32((value & (fullExtraLargeBlock << o)) >> o)
m.m[byteOffset] = result
// fmt.Printf("result at %d: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -> %032b\n", byteOffset, result)

bitsRemaining -= 32
byteOffset++
}

if bitsRemaining > 0 {
initial := uint64(m.m[byteOffset])
mask := uint64(fullBlock << bitsRemaining)
result := (initial & mask) | ((value & (^mask << writeBitCount)) >> writeBitCount)
m.m[byteOffset] = uint32(result)
writeBitCount = m.bitsPerEntry - bitsRemaining
initial := m.m[byteOffset]
mask := fullExtraLargeBlock << bitsRemaining
result := (initial & (fullBlock << bitsRemaining)) | uint32((value&((^mask)<<writeBitCount))>>writeBitCount)
m.m[byteOffset] = result

fmt.Printf("result at %d: %032b\n", byteOffset, m.m[byteOffset])
// fmt.Printf("result at %d: %032b -> %032b\n", byteOffset, initial, result)
}
}

Expand All @@ -60,36 +59,34 @@ func (m *Memories32) Read(index uint64) (result uint64) {
offset := bitsRemaining * index
bitOffset := offset % bitsInLargeBlock
byteOffset := offset / bitsInLargeBlock
fmt.Printf("\nbitOffset: %d, byteOffset: %d\n", bitOffset, byteOffset)
fmt.Printf("m.m: %x\n", m.m)
// fmt.Printf("\nbitOffset: %d, byteOffset: %d\n", bitOffset, byteOffset)
// fmt.Printf("m.m: %x\n", m.m)

readBitCount := bitsInLargeBlock - bitOffset
if readBitCount > bitsRemaining {
readBitCount = bitsRemaining
}
initial := uint64(m.m[byteOffset])
mask := uint64(^(fullBlock << readBitCount)) << bitOffset
initial := m.m[byteOffset]
mask := ^(fullBlock << readBitCount) << bitOffset
result = uint64((initial & mask) >> bitOffset)

bitsRemaining -= readBitCount
byteOffset++

if bitsRemaining > 0 {
readBitCount = bitsRemaining
if readBitCount > bitsInLargeBlock {
readBitCount = bitsInLargeBlock
}
fmt.Printf("--> %064b; %d; %d\n", result, bitsRemaining, readBitCount)
initial := uint64(m.m[byteOffset+1])
result |= ((initial & uint64(^(fullBlock << readBitCount))) << (uint64(m.bitsPerEntry) - bitsRemaining))
bitsRemaining -= readBitCount
if bitsRemaining >= 32 {
// fmt.Printf("--> %064b; %d; %d\n", result, bitsRemaining, 32)
initial := m.m[byteOffset]
result |= (uint64(initial) << (uint64(m.bitsPerEntry) - bitsRemaining))
bitsRemaining -= 32
byteOffset++
}

if bitsRemaining > 0 {
initial := uint64(m.m[byteOffset+2])
fmt.Printf("--> %064b; %d\n", result, bitsRemaining)
result |= ((initial & uint64(^(fullBlock << bitsRemaining))) << (uint64(m.bitsPerEntry) - bitsRemaining))
initial := m.m[byteOffset]
// fmt.Printf("--> %064b; %d\n", result, bitsRemaining)
result |= uint64(initial&(fullBlock>>(32-bitsRemaining))) << (uint64(m.bitsPerEntry) - bitsRemaining)
}
fmt.Printf("--> %064b\n", result)
// fmt.Printf("--> %064b\n", result)

return result
}
179 changes: 83 additions & 96 deletions memory/memory32_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package memory

import (
"fmt"
"math"
"math/rand"
"testing"
Expand Down Expand Up @@ -55,76 +56,105 @@ func evaluateLargeRead(t *testing.T, bitCount, count uint32, readIndex, expected
}

func Test_Large_Assign(t *testing.T) {
evaluateLargeAssign(t, 4, 1, 0, 0x000000000000000f, memoryMap32{0: 0x0000000f}, nil)
evaluateLargeAssign(t, 4, 2, 1, 0x000000000000000f, memoryMap32{0: 0x000000f0}, nil)
evaluateLargeAssign(t, 4, 3, 2, 0x000000000000000f, memoryMap32{0: 0x00000f00}, nil)
evaluateLargeAssign(t, 6, 2, 1, 0x000000000000003f, memoryMap32{0: 0x00000fc0}, nil)
evaluateLargeAssign(t, 11, 2, 1, 0x00000000000007ff, memoryMap32{0: 0x003ff800}, nil)
evaluateLargeAssign(t, 24, 2, 1, 0x0000000000ffffff, memoryMap32{0: 0xff000000, 1: 0xffff}, nil)
evaluateLargeAssign(t, 31, 1, 0, 0x000000002aaaaaaa, memoryMap32{0: 0x2aaaaaaa}, nil)
evaluateLargeAssign(t, 31, 1, 0, 0x0000000055555555, memoryMap32{0: 0x55555555}, nil)
evaluateLargeAssign(t, 31, 1, 0, 0x000000007fffffff, memoryMap32{0: 0x7fffffff}, nil)
evaluateLargeAssign(t, 31, 2, 1, 0x000000002aaaaaaa, memoryMap32{1: 0x15555555}, nil)
evaluateLargeAssign(t, 31, 2, 1, 0x0000000055555555, memoryMap32{0: 0x80000000, 1: 0x2aaaaaaa}, nil)
evaluateLargeAssign(t, 31, 2, 1, 0x000000007fffffff, memoryMap32{0: 0x80000000, 1: 0x3fffffff}, nil)
evaluateLargeAssign(t, 32, 1, 0, 0x0000000055555555, memoryMap32{0: 0x55555555}, nil)
evaluateLargeAssign(t, 32, 1, 0, 0x00000000aaaaaaaa, memoryMap32{0: 0xaaaaaaaa}, nil)
evaluateLargeAssign(t, 32, 1, 0, 0x00000000ffffffff, memoryMap32{0: 0xffffffff}, nil)
evaluateLargeAssign(t, 32, 2, 1, 0x0000000055555555, memoryMap32{1: 0x55555555}, nil)
evaluateLargeAssign(t, 32, 2, 1, 0x00000000aaaaaaaa, memoryMap32{1: 0xaaaaaaaa}, nil)
evaluateLargeAssign(t, 32, 2, 1, 0x00000000ffffffff, memoryMap32{1: 0xffffffff}, nil)
evaluateLargeAssign(t, 63, 1, 0, 0x5555555555555555, memoryMap32{0: 0x55555555, 1: 0x55555555}, nil)
evaluateLargeAssign(t, 63, 1, 0, 0x2aaaaaaaaaaaaaaa, memoryMap32{0: 0xaaaaaaaa, 1: 0x2aaaaaaa}, nil)
evaluateLargeAssign(t, 63, 1, 0, 0x7fffffffffffffff, memoryMap32{0: 0xffffffff, 1: 0x7fffffff}, nil)
evaluateLargeAssign(t, 63, 2, 1, 0x5555555555555555, memoryMap32{1: 0x80000000, 2: 0xaaaaaaaa, 3: 0x2aaaaaaa}, nil)
evaluateLargeAssign(t, 63, 2, 1, 0x2aaaaaaaaaaaaaaa, memoryMap32{2: 0x55555555, 3: 0x15555555}, nil)
evaluateLargeAssign(t, 63, 2, 1, 0x7fffffffffffffff, memoryMap32{1: 0x80000000, 2: 0xffffffff, 3: 0x3fffffff}, nil)
evaluateLargeAssign(t, 64, 2, 1, 0x5555555555555555, memoryMap32{2: 0x55555555, 3: 0x55555555}, nil)
evaluateLargeAssign(t, 64, 2, 1, 0xaaaaaaaaaaaaaaaa, memoryMap32{2: 0xaaaaaaaa, 3: 0xaaaaaaaa}, nil)
evaluateLargeAssign(t, 64, 2, 1, 0xffffffffffffffff, memoryMap32{2: 0xffffffff, 3: 0xffffffff}, nil)

o := &assignOptions{true}
evaluateLargeAssign(t, 4, 1, 0, 0x0, memoryMap32{0: 0xfffffff0}, o)
evaluateLargeAssign(t, 4, 2, 1, 0x0, memoryMap32{0: 0xffffff0f}, o)
evaluateLargeAssign(t, 4, 3, 2, 0x0, memoryMap32{0: 0xfffff0ff}, o)
evaluateLargeAssign(t, 6, 2, 1, 0x0, memoryMap32{0: 0xfffff03f}, o)
evaluateLargeAssign(t, 11, 2, 1, 0x0, memoryMap32{0: 0xffc007ff}, o)
evaluateLargeAssign(t, 24, 2, 1, 0x0, memoryMap32{0: 0x00ffffff, 1: 0xffff0000}, o)
evaluateLargeAssign(t, 31, 1, 0, 0x0, memoryMap32{0: 0x80000000}, o)
evaluateLargeAssign(t, 31, 2, 1, 0x0, memoryMap32{0: 0x7fffffff, 1: 0xc0000000}, o)
}

func evaluateLargeAssign(t *testing.T, bitCount, count uint32, writeIndex, value uint64, assessment memoryMap32, options *assignOptions) {
m := AllocateMemories(LargeBlock, bitCount, count)
mem := m.(*Memories32).m
if options != nil && options.initInvert {
for k := range mem {
mem[k] = 0xffffffff
}
testCases := []struct {
bitCount uint32
count uint32
writeIndex uint64
value uint64
assessment memoryMap32
options *assignOptions
}{
{4, 1, 0, 0x000000000000000f, memoryMap32{0: 0x0000000f}, nil},
{4, 2, 1, 0x000000000000000f, memoryMap32{0: 0x000000f0}, nil},
{4, 3, 2, 0x000000000000000f, memoryMap32{0: 0x00000f00}, nil},
{6, 2, 1, 0x000000000000003f, memoryMap32{0: 0x00000fc0}, nil},
{11, 2, 1, 0x00000000000007ff, memoryMap32{0: 0x003ff800}, nil},
{24, 2, 1, 0x0000000000ffffff, memoryMap32{0: 0xff000000, 1: 0xffff}, nil},
{31, 1, 0, 0x000000002aaaaaaa, memoryMap32{0: 0x2aaaaaaa}, nil},
{31, 1, 0, 0x0000000055555555, memoryMap32{0: 0x55555555}, nil},
{31, 1, 0, 0x000000007fffffff, memoryMap32{0: 0x7fffffff}, nil},
{31, 2, 1, 0x000000002aaaaaaa, memoryMap32{1: 0x15555555}, nil},
{31, 2, 1, 0x0000000055555555, memoryMap32{0: 0x80000000, 1: 0x2aaaaaaa}, nil},
{31, 2, 1, 0x000000007fffffff, memoryMap32{0: 0x80000000, 1: 0x3fffffff}, nil},
{32, 1, 0, 0x0000000055555555, memoryMap32{0: 0x55555555}, nil},
{32, 1, 0, 0x00000000aaaaaaaa, memoryMap32{0: 0xaaaaaaaa}, nil},
{32, 1, 0, 0x00000000ffffffff, memoryMap32{0: 0xffffffff}, nil},
{32, 2, 1, 0x0000000055555555, memoryMap32{1: 0x55555555}, nil},
{32, 2, 1, 0x00000000aaaaaaaa, memoryMap32{1: 0xaaaaaaaa}, nil},
{32, 2, 1, 0x00000000ffffffff, memoryMap32{1: 0xffffffff}, nil},
{63, 1, 0, 0x5555555555555555, memoryMap32{0: 0x55555555, 1: 0x55555555}, nil},
{63, 1, 0, 0x2aaaaaaaaaaaaaaa, memoryMap32{0: 0xaaaaaaaa, 1: 0x2aaaaaaa}, nil},
{63, 1, 0, 0x7fffffffffffffff, memoryMap32{0: 0xffffffff, 1: 0x7fffffff}, nil},
{63, 2, 1, 0x5555555555555555, memoryMap32{1: 0x80000000, 2: 0xaaaaaaaa, 3: 0x2aaaaaaa}, nil},
{63, 2, 1, 0x2aaaaaaaaaaaaaaa, memoryMap32{2: 0x55555555, 3: 0x15555555}, nil},
{63, 2, 1, 0x7fffffffffffffff, memoryMap32{1: 0x80000000, 2: 0xffffffff, 3: 0x3fffffff}, nil},
{64, 2, 1, 0x5555555555555555, memoryMap32{2: 0x55555555, 3: 0x55555555}, nil},
{64, 2, 1, 0xaaaaaaaaaaaaaaaa, memoryMap32{2: 0xaaaaaaaa, 3: 0xaaaaaaaa}, nil},
{64, 2, 1, 0xffffffffffffffff, memoryMap32{2: 0xffffffff, 3: 0xffffffff}, nil},

{4, 1, 0, 0x0, memoryMap32{0: 0xfffffff0}, o},
{4, 2, 1, 0x0, memoryMap32{0: 0xffffff0f}, o},
{4, 3, 2, 0x0, memoryMap32{0: 0xfffff0ff}, o},
{6, 2, 1, 0x0, memoryMap32{0: 0xfffff03f}, o},
{11, 2, 1, 0x0, memoryMap32{0: 0xffc007ff}, o},
{24, 2, 1, 0x0, memoryMap32{0: 0x00ffffff, 1: 0xffff0000}, o},
{31, 1, 0, 0x0, memoryMap32{0: 0x80000000}, o},
{31, 2, 1, 0x0, memoryMap32{0: 0x7fffffff, 1: 0xc0000000}, o},
}
m.Assign(writeIndex, value)
for k, v := range assessment {
result := uint32(mem[k])
if v != result {
t.Fatalf("At %d, incorrect result from write; expected 0x%016x, got 0x%016x\n", k, v, result)
}

for index, tc := range testCases {
t.Run(fmt.Sprintf("%d", index), func(t *testing.T) {
m := AllocateMemories(LargeBlock, tc.bitCount, tc.count)
mem := m.(*Memories32).m
if tc.options != nil && tc.options.initInvert {
for k := range mem {
mem[k] = 0xffffffff
}
}
m.Assign(tc.writeIndex, tc.value)
for k, v := range tc.assessment {
result := uint32(mem[k])
if v != result {
t.Fatalf("At %d, incorrect result from write; expected 0x%08x, got 0x%08x\n", k, v, result)
}
}
})
}
}

// func evaluateLargeAssign(t *testing.T, bitCount, count uint32, writeIndex, value uint64, assessment memoryMap32, options *assignOptions) {
// m := AllocateMemories(LargeBlock, bitCount, count)
// mem := m.(*Memories32).m
// if options != nil && options.initInvert {
// for k := range mem {
// mem[k] = 0xffffffff
// }
// }
// m.Assign(writeIndex, value)
// for k, v := range assessment {
// result := uint32(mem[k])
// if v != result {
// t.Fatalf("At %d, incorrect result from write; expected 0x%016x, got 0x%016x\n", k, v, result)
// }
// }
// }

func Test_Large_Random(t *testing.T) {
src := rand.NewSource(time.Now().UnixNano())
random := rand.New(src)

width := uint32(64 - 11)
max := int64(math.Pow(2.0, float64(width)))

count := uint64(8)
count := 8
contents := make([]uint64, count)
for i := uint64(0); i < count; i++ {
for i := 0; i < count; i++ {
contents[i] = uint64(random.Int63n(max))
}

m := AllocateMemories(LargeBlock, width, 8)
m := AllocateMemories(LargeBlock, width, uint32(count))
for k, v := range contents {
m.Assign(uint64(k), v)
}
Expand All @@ -136,46 +166,3 @@ func Test_Large_Random(t *testing.T) {
}
}
}

// func Test_WriteAndRead2(t *testing.T) {
// count := 4
// set := make([]uint64, count)
// for i := 0; i < count; i++ {
// set[i] = 0x55555555
// }
//
// m := AllocateMemories(LargeBlock, 31, 4)
//
// for k, v := range set {
// m.Assign(uint64(k), v)
// }
//
// for k, v := range set {
// result := m.Read(uint64(k))
// if result != v {
// t.Fatalf("At %d\nexpected %032b\nreceived %032b\n", k, v, result)
// }
// }
// }
//
// func Test_WriteAndRead(t *testing.T) {
// count := 4
// r := rand.New(rand.NewSource(time.Now().UnixNano()))
// set := make([]uint64, count)
// for i := 0; i < count; i++ {
// set[i] = uint64(r.Int31()) & 0x7fffffff
// }
//
// m := AllocateMemories(LargeBlock, 31, 4)
//
// for k, v := range set {
// m.Assign(uint64(k), v)
// }
//
// for k, v := range set {
// result := m.Read(uint64(k))
// if result != v {
// t.Fatalf("At %d\nexpected %032b\nreceived %032b\n", k, v, result)
// }
// }
// }
Loading

0 comments on commit 203707c

Please sign in to comment.