diff --git a/sets/README.md b/sets/README.md index d7c1ca4..8ad468a 100644 --- a/sets/README.md +++ b/sets/README.md @@ -1,3 +1,3 @@ # sets -support`interface{}`/`any` which implement Comparator interface and builtin type. +support `interface{}`/`any` which implement Comparator interface and builtin type. diff --git a/sets/set.go b/sets/set.go index 5a07f6d..b4d3a31 100644 --- a/sets/set.go +++ b/sets/set.go @@ -4,16 +4,20 @@ package sets // implemented via map[T]struct{} for minimal memory consumption. type Set[T comparable] map[T]struct{} +func newSet[T comparable](cap int) Set[T] { + return make(Set[T], cap) +} + // New creates a T from a list of values. func New[T comparable](items ...T) Set[T] { - ss := Set[T]{} - return ss.Insert(items...) + ret := newSet[T](len(items)) + return ret.Insert(items...) } // NewFrom creates a T from a keys of a map[T](? extends any). // If the value passed in is not actually a map, this will panic. func NewFrom[T comparable, V any, M ~map[T]V](m M) Set[T] { - ret := Set[T]{} + ret := newSet[T](len(m)) for k := range m { ret[k] = struct{}{} } @@ -69,7 +73,7 @@ func (s Set[T]) ContainsAny(items ...T) bool { // s1.Difference(s2) = {a3} // s2.Difference(s1) = {a4, a5}. func (s Set[T]) Difference(s2 Set[T]) Set[T] { - result := New[T]() + result := newSet[T](min(len(s), len(s2))) for key := range s { if !s2.Contains(key) { result[key] = struct{}{} @@ -85,7 +89,7 @@ func (s Set[T]) Difference(s2 Set[T]) Set[T] { // s1.Union(s2) = {a1, a2, a3, a4} // s2.Union(s1) = {a1, a2, a3, a4}. func (s Set[T]) Union(s2 Set[T]) Set[T] { - result := New[T]() + result := newSet[T](len(s) + len(s2)) for key := range s { result[key] = struct{}{} } @@ -102,7 +106,7 @@ func (s Set[T]) Union(s2 Set[T]) Set[T] { // s1.Intersection(s2) = {a2}. func (s Set[T]) Intersection(s2 Set[T]) Set[T] { var walk, other Set[T] - result := New[T]() + if s.Len() < s2.Len() { walk = s other = s2 @@ -110,12 +114,13 @@ func (s Set[T]) Intersection(s2 Set[T]) Set[T] { walk = s2 other = s } + ret := newSet[T](min(len(s), len(s2))) for key := range walk { if other.Contains(key) { - result[key] = struct{}{} + ret[key] = struct{}{} } } - return result + return ret } // Merge is like Union, however it modifies the current set it's applied on @@ -195,10 +200,5 @@ func (s Set[T]) Each(f func(item T) bool) { // Clone returns a new Set with a copy of s. func (s Set[T]) Clone() Set[T] { - ns := New[T]() - s.Each(func(item T) bool { - ns[item] = struct{}{} - return true - }) - return ns + return NewFrom(s) } diff --git a/sets/set_test.go b/sets/set_test.go index e65e203..c4d0218 100644 --- a/sets/set_test.go +++ b/sets/set_test.go @@ -1,19 +1,3 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - package sets import (