<commit_before>package meta

import (
	"sort"
	"time"

	"github.com/gogo/protobuf/proto"
	"github.com/influxdb/influxdb/influxql"
	"github.com/influxdb/influxdb/meta/internal"
)

//go:generate protoc --gogo_out=. internal/meta.proto

const (
	// DefaultRetentionPolicyReplicaN is the default value of RetentionPolicyInfo.ReplicaN.
	DefaultRetentionPolicyReplicaN = 1

	// DefaultRetentionPolicyDuration is the default value of RetentionPolicyInfo.Duration.
	DefaultRetentionPolicyDuration = 7 * (24 * time.Hour)

	// MinRetentionPolicyDuration represents the minimum duration for a policy.
	MinRetentionPolicyDuration = time.Hour
)

// Data represents the top level collection of all metadata.
type Data struct {
	Term      uint64 // associated raft term
	Index     uint64 // associated raft index
	ClusterID uint64
	Nodes     []NodeInfo
	Databases []DatabaseInfo
	Users     []UserInfo

	MaxNodeID       uint64
	MaxShardGroupID uint64
	MaxShardID      uint64
}

// Node returns a node by id.
func (data *Data) Node(id uint64) *NodeInfo {
	for i := range data.Nodes {
		if data.Nodes[i].ID == id {
			return &data.Nodes[i]
		}
	}
	return nil
}

// NodeByHost returns a node by hostname.
func (data *Data) NodeByHost(host string) *NodeInfo {
	for i := range data.Nodes {
		if data.Nodes[i].Host == host {
			return &data.Nodes[i]
		}
	}
	return nil
}

// CreateNode adds a node to the metadata.
func (data *Data) CreateNode(host string) error {
	// Ensure a node with the same host doesn't already exist.
	if data.NodeByHost(host) != nil {
		return ErrNodeExists
	}

	// Append new node.
	data.MaxNodeID++
	data.Nodes = append(data.Nodes, NodeInfo{
		ID:   data.MaxNodeID,
		Host: host,
	})

	return nil
}

// DeleteNode removes a node from the metadata.
func (data *Data) DeleteNode(id uint64, force bool) error {
	// Node has to be larger than 0 to be real
	if id == 0 {
		return ErrNodeIDRequired
	}
	// Is this a valid node?
	nodeInfo := data.Node(id)
	if nodeInfo == nil {
		return ErrNodeNotFound
	}
	// Am I the only node?  If so, nothing to do
	if len(data.Nodes) == 1 {
		return ErrNodeUnableToDropFinalNode
	}

	// Determine if there are any any non-replicated nodes and force was not specified
	if !force {
		for _, d := range data.Databases {
			for _, rp := range d.RetentionPolicies {
				// ignore replicated retention policies
				if rp.ReplicaN > 1 {
					continue
				}
				for _, sg := range rp.ShardGroups {
					for _, s := range sg.Shards {
						if s.OwnedBy(id) && len(s.Owners) == 1 {
							return ErrShardNotReplicated
						}
					}
				}
			}
		}
	}

	// Remove node id from all shard infos
	for di, d := range data.Databases {
		for ri, rp := range d.RetentionPolicies {
			// ignore replicated retention policies
			for sgi, sg := range rp.ShardGroups {
				for si, s := range sg.Shards {<commit_msg>remove comment<commit_after>package meta

import (
	"sort"
	"time"

	"github.com/gogo/protobuf/proto"
	"github.com/influxdb/influxdb/influxql"
	"github.com/influxdb/influxdb/meta/internal"
)

//go:generate protoc --gogo_out=. internal/meta.proto

const (
	// DefaultRetentionPolicyReplicaN is the default value of RetentionPolicyInfo.ReplicaN.
	DefaultRetentionPolicyReplicaN = 1

	// DefaultRetentionPolicyDuration is the default value of RetentionPolicyInfo.Duration.
	DefaultRetentionPolicyDuration = 7 * (24 * time.Hour)

	// MinRetentionPolicyDuration represents the minimum duration for a policy.
	MinRetentionPolicyDuration = time.Hour
)

// Data represents the top level collection of all metadata.
type Data struct {
	Term      uint64 // associated raft term
	Index     uint64 // associated raft index
	ClusterID uint64
	Nodes     []NodeInfo
	Databases []DatabaseInfo
	Users     []UserInfo

	MaxNodeID       uint64
	MaxShardGroupID uint64
	MaxShardID      uint64
}

// Node returns a node by id.
func (data *Data) Node(id uint64) *NodeInfo {
	for i := range data.Nodes {
		if data.Nodes[i].ID == id {
			return &data.Nodes[i]
		}
	}
	return nil
}

// NodeByHost returns a node by hostname.
func (data *Data) NodeByHost(host string) *NodeInfo {
	for i := range data.Nodes {
		if data.Nodes[i].Host == host {
			return &data.Nodes[i]
		}
	}
	return nil
}

// CreateNode adds a node to the metadata.
func (data *Data) CreateNode(host string) error {
	// Ensure a node with the same host doesn't already exist.
	if data.NodeByHost(host) != nil {
		return ErrNodeExists
	}

	// Append new node.
	data.MaxNodeID++
	data.Nodes = append(data.Nodes, NodeInfo{
		ID:   data.MaxNodeID,
		Host: host,
	})

	return nil
}

// DeleteNode removes a node from the metadata.
func (data *Data) DeleteNode(id uint64, force bool) error {
	// Node has to be larger than 0 to be real
	if id == 0 {
		return ErrNodeIDRequired
	}
	// Is this a valid node?
	nodeInfo := data.Node(id)
	if nodeInfo == nil {
		return ErrNodeNotFound
	}
	// Am I the only node?  If so, nothing to do
	if len(data.Nodes) == 1 {
		return ErrNodeUnableToDropFinalNode
	}

	// Determine if there are any any non-replicated nodes and force was not specified
	if !force {
		for _, d := range data.Databases {
			for _, rp := range d.RetentionPolicies {
				// ignore replicated retention policies
				if rp.ReplicaN > 1 {
					continue
				}
				for _, sg := range rp.ShardGroups {
					for _, s := range sg.Shards {
						if s.OwnedBy(id) && len(s.Owners) == 1 {
							return ErrShardNotReplicated
						}
					}
				}
			}
		}
	}

	// Remove node id from all shard infos
	for di, d := range data.Databases {
		for ri, rp := range d.RetentionPolicies {
			for sgi, sg := range rp.ShardGroups {
				for si, s := range sg.Shards {
{'fraction_non_alphanumeric': 0.09971509971509972, 'fraction_numerical': 0.008903133903133903, 'mean_word_length': 3.082122093023256, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '2790874', 'n_tokens_mistral': 2077, 'n_tokens_neox': 1878, 'n_words': 595}