user187676
user187676

Reputation:

Automatic cache eviction based on memory consumption

I want to implement an efficient LRU cache that automatically evicts items based on free memory.

Right now only 2 things come to mind:

Are there any other ways? How does memcached do it?

Upvotes: 3

Views: 424

Answers (1)

user187676
user187676

Reputation:

I implemented it polling the system memory statistics every 1 second.

See: https://github.com/eaigner/last

Read memory stats on Linux:

import (
    "syscall"
)

func ReadSysMemStats(s *MemStats) error {
    if s == nil {
        return nil
    }
    var info syscall.Sysinfo_t
    err := syscall.Sysinfo(&info)
    if err != nil {
        return err
    }

    s.Total = info.Totalram
    s.Free = info.Freeram
    s.Used = s.Total - s.Free

    return nil
}

And on Darwin/OSX

/*
#include <mach/mach.h>
#include <mach/mach_host.h>
*/
import "C"

import (
    "fmt"
    "unsafe"
)

func readSysMemStats(s *SysMemStats) error {
    if s == nil {
        return nil
    }
    var vm_pagesize C.vm_size_t
    var vm_stat C.vm_statistics_data_t
    var count C.mach_msg_type_number_t = C.HOST_VM_INFO_COUNT

    host_port := C.host_t(C.mach_host_self())

    C.host_page_size(host_port, &vm_pagesize)

    status := C.host_statistics(
        host_port,
        C.HOST_VM_INFO,
        C.host_info_t(unsafe.Pointer(&vm_stat)),
        &count)

    if status != C.KERN_SUCCESS {
        return fmt.Errorf("could not get vm statistics: %d", status)
    }

    // Stats in bytes
    free := uint64(vm_stat.free_count)
    active := uint64(vm_stat.active_count)
    inactive := uint64(vm_stat.inactive_count)
    wired := uint64(vm_stat.wire_count)
    pagesize := uint64(vm_pagesize)

    s.Used = (active + inactive + wired) * pagesize
    s.Free = free * pagesize
    s.Total = s.Used + s.Free

    return nil
}

Upvotes: 1

Related Questions