Skip to content

Commit

Permalink
Merge pull request #29 from Oppen/public_free
Browse files Browse the repository at this point in the history
Add public free method
  • Loading branch information
lemire authored Jun 8, 2021
2 parents 78e9e71 + 6118dd3 commit e799f2a
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
102 changes: 102 additions & 0 deletions free_test/explicit_free.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package main

import (
"fmt"
"os"
"runtime"
"syscall"

"github.com/RoaringBitmap/gocroaring"
)

// Exits with code 0 on success, 1 on test failure
// or 2 on program failure (e.g. OOM or syscall error).

func main() {
const (
N = 10000
M = 10000
)

var rusage syscall.Rusage
var maxrss_0, maxrss_free, maxrss_gc int64

fmt.Printf("Starting execution... ")
if err := syscall.Getrusage(syscall.RUSAGE_SELF, &rusage); err != nil {
fmt.Printf("Getrusage failed with error: %s\n", err)
os.Exit(2)
}
maxrss_0 = rusage.Maxrss
fmt.Printf("max RSS: %d bytes\n", maxrss_0)

bitmap := gocroaring.New()
for i := uint32(0); i < M; i++ {
bitmap.Add(i*10)
}
fmt.Printf("Created reference bitmap... ")
if err := syscall.Getrusage(syscall.RUSAGE_SELF, &rusage); err != nil {
fmt.Printf("Getrusage failed with error: %s\n", err)
os.Exit(2)
}
fmt.Printf("max RSS: %d bytes\n", rusage.Maxrss)

bitmaps := make([]*gocroaring.Bitmap, N)
fmt.Printf("Allocated slice for %d bitmap pointers... ", N)
if err := syscall.Getrusage(syscall.RUSAGE_SELF, &rusage); err != nil {
fmt.Printf("Getrusage failed with error: %s\n", err)
os.Exit(2)
}
maxrss_free = rusage.Maxrss
fmt.Printf("max RSS: %d bytes\n", maxrss_free)

for i := range bitmaps {
bitmaps[i] = bitmap.Clone()
bitmaps[i].Free()
}
fmt.Printf("Copied then explicitly freed %d bitmaps... ", N)
if err := syscall.Getrusage(syscall.RUSAGE_SELF, &rusage); err != nil {
fmt.Printf("Getrusage failed with error: %s\n", err)
os.Exit(2)
}
fmt.Printf("max RSS: %d bytes\n", rusage.Maxrss)

bitmaps = nil
runtime.GC()
fmt.Printf("GC'd old bitmaps... ")
if err := syscall.Getrusage(syscall.RUSAGE_SELF, &rusage); err != nil {
fmt.Printf("Getrusage failed with error: %s\n", err)
os.Exit(2)
}
fmt.Printf("max RSS: %d bytes\n", rusage.Maxrss)

bitmaps = make([]*gocroaring.Bitmap, N)
fmt.Printf("Allocated slice for %d bitmap pointers... ", N)
if err := syscall.Getrusage(syscall.RUSAGE_SELF, &rusage); err != nil {
fmt.Printf("Getrusage failed with error: %s\n", err)
os.Exit(2)
}
fmt.Printf("max RSS: %d bytes\n", rusage.Maxrss)

for i := range bitmaps {
bitmaps[i] = bitmap.Clone()
}
bitmaps = nil
runtime.GC()
fmt.Printf("Copied then GC'd %d bitmaps... ", N)
if err := syscall.Getrusage(syscall.RUSAGE_SELF, &rusage); err != nil {
fmt.Printf("Getrusage failed with error: %s\n", err)
os.Exit(2)
}
maxrss_gc = rusage.Maxrss
fmt.Printf("max RSS: %d bytes\n", maxrss_gc)

ballpark_free := maxrss_free - maxrss_0
ballpark_gc := maxrss_gc - maxrss_0
fmt.Printf("Used ~%d bytes with explicit free\n", ballpark_free)
fmt.Printf("Used ~%d bytes without explicit free\n", ballpark_gc)

if ballpark_gc < 100*ballpark_free {
fmt.Printf("Expected a much greater difference!\n")
os.Exit(1)
}
}
6 changes: 6 additions & 0 deletions gocroaring.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ func New(x ...uint32) *Bitmap {
return answer
}

func (rb *Bitmap) Free() {
// Clear the finalizer to avoid double frees
runtime.SetFinalizer(rb, nil)
free(rb)
}

// Printf writes a description of the bitmap to stdout
func (rb *Bitmap) Printf() {
fmt.Print("{")
Expand Down
9 changes: 9 additions & 0 deletions gocroaring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package gocroaring
import (
"fmt"
"math/rand"
"os/exec"
"reflect"
"runtime"
"testing"
Expand Down Expand Up @@ -57,6 +58,14 @@ func TestMemoryUsage(t *testing.T) {
}
}

func TestExplicitFree(t *testing.T) {
output, err := exec.Command("go", "run", "free_test/explicit_free.go").Output()
if err != nil {
t.Errorf("Command exited with error: %s", err)
}
fmt.Printf("TestExplicitFree output:\n%s\n", output)
}

func TestSimpleCard(t *testing.T) {
bitmap := New()
for i := 100; i < 1000; i++ {
Expand Down

0 comments on commit e799f2a

Please sign in to comment.