<commit_before>package citadel

import (
	"encoding/json"
	"path/filepath"

	"github.com/coreos/go-etcd/etcd"
)

type Registry struct {
	client *etcd.Client
}

func NewRegistry(machines []string) *Registry {
	return &Registry{
		client: etcd.NewClient(machines),
	}
}

func (r *Registry) FetchContainers(h *Host) ([]*Container, error) {
	resp, err := r.client.Get(filepath.Join("/citadel", h.ID, "containers"), true, true)
	if err != nil {
		return nil, err
	}

	out := []*Container{}
	for _, node := range resp.Node.Nodes {
		var container *Container
		if err := json.Unmarshal([]byte(node.Value), &container); err != nil {
			return nil, err
		}

		out = append(out, container)
	}

	return out, nil
}

func (r *Registry) FetchContainer(h *Host, id string) (*Container, error) {
	resp, err := r.client.Get(filepath.Join("/citadel", h.ID, "containers", id), false, false)
	if err != nil {
		return nil, err
	}

	var container *Container
	if err := json.Unmarshal([]byte(resp.Node.Value), &container); err != nil {
		return nil, err
	}

	return container, nil
}

func (r *Registry) SaveContainer(h *Host, c *Container) error {
	data, err := json.Marshal(c)
	if err != nil {
		return err
	}

	if _, err := r.client.Set(filepath.Join("/citadel", h.ID, "containers", c.ID), string(data), 0); err != nil {
		return err
	}

	return nil
}

func (r *Registry) DeleteContainer(h *Host, c *Container) error {
	_, err := r.client.Delete(filepath.Join("/citadel", h.ID, "containers", c.ID), false)
	return err
}

func (r *Registry) SaveHost(h *Host) error {
	data, err := json.Marshal(h)
	if err != nil {
		return err
	}

	if _, err := r.client.Set(filepath.Join("/citadel/hosts", h.ID), string(data), 0); err != nil {
		return err
	}

	return nil
}

func (r *Registry) FetchHosts() ([]*Host, error) {
	hosts := []*Host{}

	resp, err := r.client.Get("/citadel/hosts", true, true)
	if err != nil {
		return nil, err
	}

	for _, n := range resp.Node.Nodes {
		var host *Host
		if err := json.Unmarshal([]byte(n.Value), &host); err != nil {
			return nil, err
		}

		hosts = append(hosts, host)
	}

	return hosts, nil
}

func (r *Registry) DeleteHost(h *Host) error {
	_, err := r.client.Delete(filepath.Join("/citadel/hosts", h.ID), false)
	return err
}<commit_msg>Fix is not found errors when no hosts or containers<commit_after>package citadel

import (
	"encoding/json"
	"path/filepath"
	"strings"

	"github.com/coreos/go-etcd/etcd"
)

type Registry struct {
	client *etcd.Client
}

func NewRegistry(machines []string) *Registry {
	return &Registry{
		client: etcd.NewClient(machines),
	}
}

func (r *Registry) FetchContainers(h *Host) ([]*Container, error) {
	out := []*Container{}

	resp, err := r.client.Get(filepath.Join("/citadel", h.ID, "containers"), true, true)
	if err != nil {
		if isNotFound(err) {
			return out, nil
		}
		return nil, err
	}

	for _, node := range resp.Node.Nodes {
		var container *Container
		if err := json.Unmarshal([]byte(node.Value), &container); err != nil {
			return nil, err
		}

		out = append(out, container)
	}

	return out, nil
}

func (r *Registry) FetchContainer(h *Host, id string) (*Container, error) {
	resp, err := r.client.Get(filepath.Join("/citadel", h.ID, "containers", id), false, false)
	if err != nil {
		return nil, err
	}

	var container *Container
	if err := json.Unmarshal([]byte(resp.Node.Value), &container); err != nil {
		return nil, err
	}

	return container, nil
}

func (r *Registry) SaveContainer(h *Host, c *Container) error {
	data, err := json.Marshal(c)
	if err != nil {
		return err
	}

	if _, err := r.client.Set(filepath.Join("/citadel", h.ID, "containers", c.ID), string(data), 0); err != nil {
		return err
	}

	return nil
}

func (r *Registry) DeleteContainer(h *Host, c *Container) error {
	_, err := r.client.Delete(filepath.Join("/citadel", h.ID, "containers", c.ID), false)
	return err
}

func (r *Registry) SaveHost(h *Host) error {
	data, err := json.Marshal(h)
	if err != nil {
		return err
	}

	if _, err := r.client.Set(filepath.Join("/citadel/hosts", h.ID), string(data), 0); err != nil {
		return err
	}

	return nil
}

func (r *Registry) FetchHosts() ([]*Host, error) {
	hosts := []*Host{}

	resp, err := r.client.Get("/citadel/hosts", true, true)
	if err != nil {
		if isNotFound(err) {
			return hosts, nil
		}
		return nil, err
	}

	for _, n := range resp.Node.Nodes {
		var host *Host
		if err := json.Unmarshal([]byte(n.Value), &host); err != nil {
			return nil, err
		}

		hosts = append(hosts, host)
	}

	return hosts, nil
}

func (r *Registry) DeleteHost(h *Host) error {
	_, err := r.client.Delete(filepath.Join("/citadel/hosts", h.ID), false)
	return err
}

func isNotFound(err error) bool {
	return strings.Contains(err.Error(), "Key not found")
}
{'fraction_non_alphanumeric': 0.17032503165892782, 'fraction_numerical': 0.0008442380751371887, 'mean_word_length': 3.7484969939879758, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2517560', 'n_tokens_mistral': 1825, 'n_tokens_neox': 1712, 'n_words': 481}