fatal error: xxhash.h: No such file or directory

When trying to compile a project, I started to receive the error fatal error: xxhash.h: No such file or directory. I tried to install liblz4-dev, but that didn’t seem to fix the error (looking at the repo, it looks as though xxhash was removed in revision 123).

Eventually, I decided to just download the relevant files and place them in /usr/include which fixed the issue,

cd /usr/include
sudo wget http://lz4.googlecode.com/svn-history/r122/trunk/programs/xxhash.c
sudo wget http://lz4.googlecode.com/svn-history/r122/trunk/programs/xxhash.h

Then, when I tried to compile the project it worked fine

golang: How to `go get` private repos

Recently, I’ve been working on some golang projects at DataSift that depend on some private modules. This means that when I run go get to fetch the module, Github asks me for my username and password. Unfortunately, as I use 2FA I need to generate a new, temporary password for applications that want my password. As go get doesn’t cache credentials, I’d have to do this every time I needed a private repo. Instead, I wanted to force go get to use my SSH key.

Fortunately, as go get uses git, you can change your .gitconfig to force it to use SSH.

$ git config --global url."git@github.com:".insteadOf "https://github.com/"
$ cat ~/.gitconfig
[url "git@github.com:"]
    insteadOf = https://github.com/

Here, we say use git@github.com any time you’d use https://github.com. This works for everything, not just go get. It just has the nice side effect of using your SSH key any time you run go get too.

Golang: Using Memcached

If you want to use memcached in a Golang project, the most recommended library is is memcache from Brad Fitzpatrick. Brad is both the author of memcache and a Golang core team member, which means that we can trust the library that he wrote.

Installation

First, we need to install the library:

go get github.com/bradfitz/gomemcache/memcache

Cheatsheet

Here’s the miinimum you need to know to use memcached

Connect to memcache
    mc := memcache.New("127.0.0.1:11211")
    // => memcache.Client (http://godoc.org/github.com/bradfitz/gomemcache/memcache#Client)
Set a value
    err := mc.Set(&memcache.Item{Key: "key_one", Value: []byte("michael")})
    // => Error
Get a value
    val, err := mc.Get("key_one")
    // => memcache.Item, Error
Get multiple values
    it, err := mc.GetMulti([]string{"key_one", "key_two"})
    // => map[string]memcache.Item, Error

Putting it all together

Then we can write a small program to talk to our memcached server

package main

import (
    "fmt"

    "github.com/bradfitz/gomemcache/memcache"
)

func main() {

    // Connect to our memcache instance
    mc := memcache.New("127.0.0.1:11211")

    // Set some values
    mc.Set(&memcache.Item{Key: "key_one", Value: []byte("michael")})
    mc.Set(&memcache.Item{Key: "key_two", Value: []byte("programming")})

    // Get a single value
    val, err := mc.Get("key_one")

    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Printf("-- %s", val.Value)

    // Get multiple values
    it, err := mc.GetMulti([]string{"key_one", "key_two"})

    if err != nil {
        fmt.Println(err)
        return
    }

    // It's important to note here that `range` iterates in a *random* order
    for k, v := range it {
        fmt.Printf("## %s => %s\n", k, v.Value)
    }

}

The return values from memcache will be wrapped in a memcache.Item type. You can find the documentation that shows it’s properties here