Skip to content

Commit

Permalink
initial memoization support for nix build result
Browse files Browse the repository at this point in the history
  • Loading branch information
corpix committed Aug 14, 2022
1 parent 98aebab commit 578fc49
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
71 changes: 70 additions & 1 deletion provider/nix.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/url"
"strconv"
"strings"
"sync"
)

type (
Expand All @@ -25,6 +26,8 @@ type (
NixBuildCommand struct {
Nix *Nix
Arguments []string
Memoize bool
MemoKey string
Unmarshaler
}
NixBuildCommandOption func(*NixBuildCommand)
Expand Down Expand Up @@ -63,6 +66,13 @@ type (
Outputs map[string]string `json:"outputs" mapstructure:"outputs"`
}
Derivations []Derivation

//

Memo struct {
sync.RWMutex
Store map[string][]byte
}
)

const (
Expand Down Expand Up @@ -97,6 +107,12 @@ const (
NixActivationActionDryActivate NixActivationAction = "dry-activate"
)

var (
nixBuildCommandMemo = &Memo{
Store: map[string][]byte{},
}
)

func (n NixCopyProtocol) Path(path string) string {
u := &url.URL{}
if len(n) > 0 {
Expand Down Expand Up @@ -179,14 +195,52 @@ func NixBuildCommandOptionJSON() NixBuildCommandOption {
}
}

func NixBuildCommandOptionMemoize(key string) NixBuildCommandOption {
return func(n *NixBuildCommand) {
n.Memoize = true
n.MemoKey = key
}
}

func (n *NixBuildCommand) Command() (string, []string, []CommandOption) {
command, arguments, options := n.Nix.Command()
return command, append(append(arguments, "build"), n.Arguments...), options
}

func (n *NixBuildCommand) Execute(result interface{}) error {
var (
r []byte
ok bool
err error
)
command, arguments, options := n.Command()
return CommandExecuteUnmarshal(command, arguments, n.Unmarshaler, result, options...)
if n.Memoize {
r, ok = nixBuildCommandMemo.Get(n.MemoKey)
if ok {
goto unmarshal
}
}

r, err = CommandExecute(command, arguments, options...)
if err != nil {
return err
}
if n.Memoize {
nixBuildCommandMemo.Set(n.MemoKey, r)
}

unmarshal:
if result != nil {
unmarshaler := n.Unmarshaler
if unmarshaler == nil {
unmarshaler = NewUnmarshalerPassthrough()
}
err := unmarshaler.Unmarshal(r, &result)
if err != nil {
return err
}
}
return nil
}

func (n *NixBuildCommand) Close() error { return nil }
Expand Down Expand Up @@ -422,3 +476,18 @@ func (d Derivation) Hash() string {
}
return hex.EncodeToString(hash.Sum(nil))
}

//

func (m *Memo) Get(key string) ([]byte, bool) {
m.RLock()
defer m.RUnlock()
v, ok := m.Store[key]
return v, ok
}

func (m *Memo) Set(key string, value []byte) {
m.Lock()
defer m.Unlock()
m.Store[key] = value
}
1 change: 1 addition & 0 deletions provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ func (p *Provider) Build(ctx context.Context, resource ResourceBox) (Derivations
NixBuildCommandOptionArgStr("configuration", configurationAbs),
NixBuildCommandOptionJSON(),
NixBuildCommandOptionNoLink(),
NixBuildCommandOptionMemoize(configurationAbs),
)
defer command.Close()

Expand Down

0 comments on commit 578fc49

Please sign in to comment.