using System; using System.Collections.ObjectModel; using System.Linq; using FrostFS.Netmap; using FrostFS.SDK.Client; namespace FrostFS.SDK; public struct FrostFsPlacementPolicy(bool unique, uint backupFactor, Collection selectors, Collection filters, params FrostFsReplica[] replicas) : IEquatable { private PlacementPolicy? policy; public FrostFsReplica[] Replicas { get; } = replicas; public Collection Selectors { get; } = selectors; public Collection Filters { get; } = filters; public bool Unique { get; } = unique; public uint BackupFactor { get; } = backupFactor; public override readonly bool Equals(object obj) { if (obj is null) { return false; } var other = (FrostFsPlacementPolicy)obj; return Equals(other); } public PlacementPolicy GetPolicy() { if (policy == null) { policy = new PlacementPolicy { Filters = { }, Selectors = { }, Replicas = { }, Unique = Unique, ContainerBackupFactor = BackupFactor }; if (Selectors != null && Selectors.Count > 0) { policy.Selectors.AddRange(Selectors.Select(s => s.GetMessage())); } if (Filters != null && Filters.Count > 0) { policy.Filters.AddRange(Filters.Select(s => s.ToMessage())); } foreach (var replica in Replicas) { policy.Replicas.Add(replica.ToMessage()); } } return policy; } internal readonly bool IsUnique() { return Unique || Replicas.Any(r => r.EcDataCount != 0 || r.EcParityCount != 0); } public override readonly int GetHashCode() { return Unique ? 17 : 0 + Replicas.GetHashCode(); } public static bool operator ==(FrostFsPlacementPolicy left, FrostFsPlacementPolicy right) { return left.Equals(right); } public static bool operator !=(FrostFsPlacementPolicy left, FrostFsPlacementPolicy right) { return !(left == right); } public readonly bool Equals(FrostFsPlacementPolicy other) { var notEqual = Unique != other.Unique || Replicas.Length != other.Replicas.Length; if (notEqual) return false; foreach (var replica in Replicas) { if (!other.Replicas.Any(r => r.Equals(replica))) return false; } return true; } }