// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package stringset provides a way to represent a collection of strings // compactly.
package stringset import // A Set holds a collection of strings that can be looked up by an index number. type Set struct { // These fields are exported to allow for code generation. Data string Index []uint16 } // Elem returns the string with index i. It panics if i is out of range. func ( *Set) ( int) string { return .Data[.Index[]:.Index[+1]] } // Len returns the number of strings in the set. func ( *Set) () int { return len(.Index) - 1 } // Search returns the index of the given string or -1 if it is not in the set. // The Set must have been created with strings in sorted order. func ( *Set, string) int { // TODO: optimize this if it gets used a lot. := len(.Index) - 1 := sort.Search(, func( int) bool { return .Elem() >= }) if == || != .Elem() { return -1 } return } // A Builder constructs Sets. type Builder struct { set Set index map[string]int } // NewBuilder returns a new and initialized Builder. func () *Builder { return &Builder{ set: Set{ Index: []uint16{0}, }, index: map[string]int{}, } } // Set creates the set created so far. func ( *Builder) () Set { return .set } // Index returns the index for the given string, which must have been added // before. func ( *Builder) ( string) int { return .index[] } // Add adds a string to the index. Strings that are added by a single Add will // be stored together, unless they match an existing string. func ( *Builder) ( ...string) { // First check if the string already exists. for , := range { if , := .index[]; { continue } .index[] = len(.set.Index) - 1 .set.Data += := len(.set.Data) if > 0xFFFF { panic("Index too > 0xFFFF") } .set.Index = append(.set.Index, uint16()) } }