gitlab.com/evatix-go/core@v1.3.55/coredata/corestr/CharCollectionMap.go (about)

     1  package corestr
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"sort"
     7  	"strings"
     8  	"sync"
     9  
    10  	"gitlab.com/evatix-go/core/constants"
    11  	"gitlab.com/evatix-go/core/coredata/corejson"
    12  	"gitlab.com/evatix-go/core/coreindexes"
    13  )
    14  
    15  type CharCollectionMap struct {
    16  	items                  map[byte]*Collection
    17  	eachCollectionCapacity int
    18  	sync.Mutex
    19  }
    20  
    21  func (it *CharCollectionMap) GetChar(
    22  	str string,
    23  ) byte {
    24  	if str != "" {
    25  		return str[coreindexes.First]
    26  	}
    27  
    28  	return emptyChar
    29  }
    30  
    31  func (it *CharCollectionMap) GetCharOfPtr(
    32  	str *string,
    33  ) byte {
    34  	if str == nil || *str == "" {
    35  		return emptyChar
    36  	}
    37  
    38  	return (*str)[coreindexes.First]
    39  }
    40  
    41  func (it *CharCollectionMap) GetCharsPtrGroups(
    42  	items *[]string,
    43  ) *CharCollectionMap {
    44  	if items == nil || *items == nil {
    45  		return it
    46  	}
    47  
    48  	length := len(*items)
    49  	lenBy4 := length / 3
    50  
    51  	if lenBy4 < defaultEachCollectionCapacity {
    52  		lenBy4 = defaultEachCollectionCapacity
    53  	}
    54  
    55  	if length == 0 {
    56  		return nil
    57  	}
    58  
    59  	collectionMap := New.CharCollectionMap.CapSelfCap(
    60  		length,
    61  		length/3)
    62  
    63  	return collectionMap.AddStringsPtr(items)
    64  }
    65  
    66  func (it *CharCollectionMap) GetMap() map[byte]*Collection {
    67  	return it.items
    68  }
    69  
    70  // GetCopyMapLock Sends a copy of items
    71  func (it *CharCollectionMap) GetCopyMapLock() map[byte]*Collection {
    72  	it.Lock()
    73  	defer it.Unlock()
    74  
    75  	if it.IsEmpty() {
    76  		return map[byte]*Collection{}
    77  	}
    78  
    79  	// TODO Fix copy logic
    80  	return it.items
    81  }
    82  
    83  func (it *CharCollectionMap) SummaryStringLock() string {
    84  	length := it.LengthLock()
    85  	collectionOfCollection := make(
    86  		[]string,
    87  		length+1)
    88  
    89  	collectionOfCollection[coreindexes.First] = fmt.Sprintf(
    90  		summaryOfCharCollectionMapLengthFormat,
    91  		it,
    92  		length,
    93  		coreindexes.First)
    94  
    95  	i := 1
    96  	for key, collection := range it.GetCopyMapLock() {
    97  		collectionOfCollection[i] = fmt.Sprintf(
    98  			charCollectionMapSingleItemFormat,
    99  			i+1,
   100  			string(key),
   101  			collection.LengthLock())
   102  
   103  		i++
   104  	}
   105  
   106  	return strings.Join(
   107  		collectionOfCollection,
   108  		constants.EmptyString)
   109  }
   110  
   111  func (it *CharCollectionMap) SummaryString() string {
   112  	collectionOfCollection := make(
   113  		[]string,
   114  		it.Length()+1)
   115  
   116  	collectionOfCollection[coreindexes.First] = fmt.Sprintf(
   117  		summaryOfCharCollectionMapLengthFormat,
   118  		it,
   119  		it.Length(),
   120  		coreindexes.First+1)
   121  
   122  	i := 1
   123  	for key, collection := range it.items {
   124  		collectionOfCollection[i] = fmt.Sprintf(
   125  			charCollectionMapSingleItemFormat,
   126  			i,
   127  			string(key),
   128  			collection.Length())
   129  
   130  		i++
   131  	}
   132  
   133  	return strings.Join(
   134  		collectionOfCollection,
   135  		constants.EmptyString)
   136  }
   137  
   138  func (it *CharCollectionMap) String() string {
   139  	collectionOfCollection := make(
   140  		[]string,
   141  		it.Length()*2+1)
   142  
   143  	collectionOfCollection[coreindexes.First] =
   144  		it.SummaryString()
   145  
   146  	i := 1
   147  	for key, collection := range it.items {
   148  		collectionOfCollection[i] = fmt.Sprintf(
   149  			charCollectionMapLengthFormat,
   150  			string(key))
   151  
   152  		i++
   153  		collectionOfCollection[i] = collection.String()
   154  		i++
   155  	}
   156  
   157  	return strings.Join(
   158  		collectionOfCollection,
   159  		constants.EmptyString)
   160  }
   161  
   162  func (it *CharCollectionMap) SortedListAsc() *[]string {
   163  	list := it.List()
   164  	sort.Strings(*list)
   165  
   166  	return list
   167  }
   168  
   169  func (it *CharCollectionMap) StringLock() string {
   170  	collectionOfCollection := make(
   171  		[]string,
   172  		it.LengthLock()*2+1)
   173  
   174  	collectionOfCollection[coreindexes.First] =
   175  		it.SummaryStringLock()
   176  
   177  	i := 1
   178  	for key, collection := range it.GetCopyMapLock() {
   179  		collectionOfCollection[i] = fmt.Sprintf(
   180  			charCollectionMapLengthFormat,
   181  			string(key))
   182  
   183  		i++
   184  		collectionOfCollection[i] =
   185  			collection.StringLock()
   186  		i++
   187  	}
   188  
   189  	return strings.Join(
   190  		collectionOfCollection,
   191  		constants.EmptyString)
   192  }
   193  
   194  func (it *CharCollectionMap) Print(isPrint bool) {
   195  	if !isPrint {
   196  		return
   197  	}
   198  
   199  	fmt.Println(
   200  		it.String(),
   201  	)
   202  }
   203  
   204  func (it *CharCollectionMap) PrintLock(isPrint bool) {
   205  	if !isPrint {
   206  		return
   207  	}
   208  
   209  	fmt.Println(
   210  		it.StringLock(),
   211  	)
   212  }
   213  
   214  func (it *CharCollectionMap) IsEmpty() bool {
   215  	return it == nil ||
   216  		len(it.items) == 0
   217  }
   218  
   219  func (it *CharCollectionMap) HasItems() bool {
   220  	return !it.IsEmpty()
   221  }
   222  
   223  func (it *CharCollectionMap) IsEmptyLock() bool {
   224  	it.Lock()
   225  	defer it.Unlock()
   226  
   227  	return it.IsEmpty()
   228  }
   229  
   230  // LengthOfCollectionFromFirstChar Get the char of the string given and get the length of how much is there.
   231  func (it *CharCollectionMap) LengthOfCollectionFromFirstChar(
   232  	str string,
   233  ) int {
   234  	char := it.GetChar(str)
   235  
   236  	collection, has := it.items[char]
   237  
   238  	if has {
   239  		return collection.Length()
   240  	}
   241  
   242  	return 0
   243  }
   244  
   245  func (it *CharCollectionMap) Has(
   246  	str string,
   247  ) bool {
   248  	if it.IsEmpty() {
   249  		return false
   250  	}
   251  
   252  	char := it.
   253  		GetChar(str)
   254  
   255  	collection, has := it.items[char]
   256  
   257  	if has {
   258  		return collection.Has(str)
   259  	}
   260  
   261  	return false
   262  }
   263  
   264  func (it *CharCollectionMap) HasWithCollection(
   265  	str string,
   266  ) (bool, *Collection) {
   267  	if it.IsEmpty() {
   268  		return false, Empty.Collection()
   269  	}
   270  
   271  	char := it.
   272  		GetChar(str)
   273  
   274  	collection, has := it.items[char]
   275  
   276  	if has {
   277  		return collection.Has(str), collection
   278  	}
   279  
   280  	return false, Empty.Collection()
   281  }
   282  
   283  func (it *CharCollectionMap) HasWithCollectionLock(
   284  	str string,
   285  ) (bool, *Collection) {
   286  	it.Lock()
   287  	defer it.Unlock()
   288  
   289  	if it.IsEmpty() {
   290  		return false, Empty.Collection()
   291  	}
   292  
   293  	char := it.
   294  		GetChar(str)
   295  
   296  	collection, has := it.items[char]
   297  
   298  	if has {
   299  		return collection.HasLock(str), collection
   300  	}
   301  
   302  	return false, Empty.Collection()
   303  }
   304  
   305  func (it *CharCollectionMap) LengthOf(char byte) int {
   306  	if it.IsEmpty() {
   307  		return 0
   308  	}
   309  
   310  	collection, has := it.items[char]
   311  
   312  	if has {
   313  		return collection.Length()
   314  	}
   315  
   316  	return 0
   317  }
   318  
   319  func (it *CharCollectionMap) LengthOfLock(char byte) int {
   320  	it.Lock()
   321  	defer it.Unlock()
   322  
   323  	if it.IsEmpty() {
   324  		return 0
   325  	}
   326  
   327  	collection, has := it.items[char]
   328  
   329  	if has {
   330  		return collection.Length()
   331  	}
   332  
   333  	return 0
   334  }
   335  
   336  // AllLengthsSum All lengths sum.
   337  func (it *CharCollectionMap) AllLengthsSum() int {
   338  	if it == nil || it.items == nil {
   339  		return 0
   340  	}
   341  
   342  	allLengthsSum := 0
   343  
   344  	for _, collection := range it.items {
   345  		allLengthsSum += collection.Length()
   346  	}
   347  
   348  	return allLengthsSum
   349  }
   350  
   351  // AllLengthsSumLock All lengths sum.
   352  func (it *CharCollectionMap) AllLengthsSumLock() int {
   353  	it.Lock()
   354  	defer it.Unlock()
   355  
   356  	if it == nil || it.items == nil {
   357  		return 0
   358  	}
   359  
   360  	allLengthsSum := 0
   361  
   362  	for _, collection := range it.items {
   363  		allLengthsSum += collection.LengthLock()
   364  	}
   365  
   366  	return allLengthsSum
   367  }
   368  
   369  // Length Returns the length of chars which is the map length.
   370  func (it *CharCollectionMap) Length() int {
   371  	if it == nil || it.items == nil {
   372  		return 0
   373  	}
   374  
   375  	return len(it.items)
   376  }
   377  
   378  func (it *CharCollectionMap) LengthLock() int {
   379  	it.Lock()
   380  	defer it.Unlock()
   381  
   382  	if it == nil || it.items == nil {
   383  		return 0
   384  	}
   385  
   386  	return len(it.items)
   387  }
   388  
   389  func (it *CharCollectionMap) IsEqualsPtrLock(
   390  	another *CharCollectionMap,
   391  ) bool {
   392  	it.Lock()
   393  	defer it.Unlock()
   394  
   395  	return it.IsEqualsWithCaseSensitivityPtr(
   396  		another,
   397  		true)
   398  }
   399  
   400  func (it *CharCollectionMap) IsEqualsPtr(
   401  	another *CharCollectionMap,
   402  ) bool {
   403  	return it.IsEqualsWithCaseSensitivityPtr(
   404  		another,
   405  		true)
   406  }
   407  
   408  func (it *CharCollectionMap) IsEqualsWithCaseSensitivityPtrLock(
   409  	another *CharCollectionMap,
   410  	isCaseSensitive bool,
   411  ) bool {
   412  	it.Lock()
   413  	defer it.Unlock()
   414  
   415  	return it.IsEqualsWithCaseSensitivityPtr(
   416  		another,
   417  		isCaseSensitive)
   418  }
   419  
   420  func (it *CharCollectionMap) IsEqualsWithCaseSensitivityPtr(
   421  	another *CharCollectionMap,
   422  	isCaseSensitive bool,
   423  ) bool {
   424  	if another == nil {
   425  		return false
   426  	}
   427  
   428  	if another == it {
   429  		return true
   430  	}
   431  
   432  	if another.IsEmpty() && it.IsEmpty() {
   433  		return true
   434  	}
   435  
   436  	if another.IsEmpty() || it.IsEmpty() {
   437  		return false
   438  	}
   439  
   440  	if another.Length() != it.Length() {
   441  		return false
   442  	}
   443  
   444  	leftMap := it.items
   445  	rightMap := another.items
   446  
   447  	for key, collection := range leftMap {
   448  		rCollection, has := rightMap[key]
   449  
   450  		if !has {
   451  			return false
   452  		}
   453  
   454  		if !rCollection.IsEqualsWithSensitivePtr(
   455  			collection,
   456  			isCaseSensitive) {
   457  			return false
   458  		}
   459  	}
   460  
   461  	return true
   462  }
   463  
   464  func (it *CharCollectionMap) AddLock(
   465  	str string,
   466  ) *CharCollectionMap {
   467  	char := it.GetChar(str)
   468  
   469  	it.Lock()
   470  	collection, has := it.items[char]
   471  	it.Unlock()
   472  
   473  	if has {
   474  		collection.AddLock(str)
   475  
   476  		return it
   477  	}
   478  
   479  	newCollection := New.Collection.Cap(it.eachCollectionCapacity)
   480  	newCollection.Add(str)
   481  
   482  	it.Lock()
   483  	it.items[char] = newCollection
   484  	it.Unlock()
   485  
   486  	return it
   487  }
   488  
   489  func (it *CharCollectionMap) Add(
   490  	str string,
   491  ) *CharCollectionMap {
   492  	char := it.GetChar(str)
   493  
   494  	collection, has := it.items[char]
   495  
   496  	if has {
   497  		collection.Add(str)
   498  
   499  		return it
   500  	}
   501  
   502  	newCollection := New.Collection.Cap(it.eachCollectionCapacity)
   503  	newCollection.Add(str)
   504  	it.items[char] = newCollection
   505  
   506  	return it
   507  }
   508  
   509  func (it *CharCollectionMap) AddStringPtr(
   510  	str *string,
   511  ) *CharCollectionMap {
   512  	char := it.GetCharOfPtr(str)
   513  
   514  	collection, has := it.items[char]
   515  
   516  	if has {
   517  		collection.AddPtr(str)
   518  
   519  		return it
   520  	}
   521  
   522  	newCollection := New.Collection.Cap(it.eachCollectionCapacity)
   523  	newCollection.AddPtr(str)
   524  	it.items[char] = newCollection
   525  
   526  	return it
   527  }
   528  
   529  func (it *CharCollectionMap) AddStringPtrLock(
   530  	str *string,
   531  ) *CharCollectionMap {
   532  	defer it.Unlock()
   533  	char := it.GetCharOfPtr(str)
   534  
   535  	it.Lock()
   536  	collection, has := it.items[char]
   537  	it.Unlock()
   538  
   539  	if has {
   540  		collection.AddPtrLock(str)
   541  
   542  		return it
   543  	}
   544  
   545  	newCollection := New.Collection.Cap(it.eachCollectionCapacity)
   546  	newCollection.AddPtr(str)
   547  
   548  	it.Lock()
   549  	it.items[char] = newCollection
   550  	it.Unlock()
   551  
   552  	return it
   553  }
   554  
   555  // AddSameStartingCharItems Assuming all items starts with same chars
   556  func (it *CharCollectionMap) AddSameStartingCharItems(
   557  	char byte,
   558  	allItemsWithSameChar []string,
   559  	isCloneAdd bool,
   560  ) *CharCollectionMap {
   561  	if len(allItemsWithSameChar) == 0 {
   562  		return it
   563  	}
   564  
   565  	values, has := it.items[char]
   566  
   567  	if has {
   568  		values.Adds(allItemsWithSameChar...)
   569  
   570  		return it
   571  	}
   572  
   573  	it.items[char] =
   574  		New.Collection.StringsOptions(
   575  			isCloneAdd,
   576  			allItemsWithSameChar,
   577  		)
   578  
   579  	return it
   580  }
   581  
   582  func (it *CharCollectionMap) AddPtrStringsLock(
   583  	simpleStrings *[]*string,
   584  ) *CharCollectionMap {
   585  	if simpleStrings == nil ||
   586  		*simpleStrings == nil ||
   587  		len(*simpleStrings) == 0 {
   588  		return it
   589  	}
   590  
   591  	for _, item := range *simpleStrings {
   592  		foundCollection := it.GetCollectionLock(
   593  			*item, true)
   594  
   595  		foundCollection.AddPtrLock(item)
   596  	}
   597  
   598  	return it
   599  }
   600  
   601  func (it *CharCollectionMap) AddHashmapsValues(
   602  	hashmaps ...*Hashmap,
   603  ) *CharCollectionMap {
   604  	if hashmaps == nil {
   605  		return it
   606  	}
   607  
   608  	for _, hashmap := range hashmaps {
   609  		if hashmap == nil || hashmap.IsEmpty() {
   610  			continue
   611  		}
   612  
   613  		for _, v := range hashmap.items {
   614  			vc := v
   615  			it.AddStringPtr(&vc)
   616  		}
   617  	}
   618  
   619  	return it
   620  }
   621  
   622  func (it *CharCollectionMap) AddHashmapsKeysOrValuesBothUsingFilter(
   623  	filter IsKeyValueFilter,
   624  	hashmaps ...*Hashmap,
   625  ) *CharCollectionMap {
   626  	if hashmaps == nil {
   627  		return it
   628  	}
   629  
   630  	for _, hashmap := range hashmaps {
   631  		if hashmap == nil || hashmap.IsEmpty() {
   632  			continue
   633  		}
   634  
   635  		for k, v := range hashmap.items {
   636  			result, isAccept, isBreak := filter(KeyValuePair{
   637  				Key:   k,
   638  				Value: v,
   639  			})
   640  
   641  			if isAccept {
   642  				it.AddStringPtr(&result)
   643  			}
   644  
   645  			if isBreak {
   646  				return it
   647  			}
   648  		}
   649  	}
   650  
   651  	return it
   652  }
   653  
   654  func (it *CharCollectionMap) AddHashmapsKeysValuesBoth(
   655  	hashmaps ...*Hashmap,
   656  ) *CharCollectionMap {
   657  	if hashmaps == nil {
   658  		return it
   659  	}
   660  
   661  	for _, hashmap := range hashmaps {
   662  		if hashmap.IsEmpty() {
   663  			continue
   664  		}
   665  
   666  		for k, v := range hashmap.items {
   667  			vc := v
   668  			kc := k
   669  			it.AddStringPtr(&vc)
   670  			it.AddStringPtr(&kc)
   671  		}
   672  	}
   673  
   674  	return it
   675  }
   676  
   677  func (it *CharCollectionMap) AddStringsPtrAsyncLock(
   678  	largeStringsCollection *[]string,
   679  	onComplete OnCompleteCharCollectionMap,
   680  ) *CharCollectionMap {
   681  	if largeStringsCollection == nil ||
   682  		*largeStringsCollection == nil {
   683  		return it
   684  	}
   685  
   686  	length := len(*largeStringsCollection)
   687  
   688  	if length == 0 {
   689  		return it
   690  	}
   691  
   692  	isListIsTooLargeAndHasExistingData :=
   693  		length > RegularCollectionEfficiencyLimit &&
   694  			it.Length() > DoubleLimit
   695  
   696  	if isListIsTooLargeAndHasExistingData {
   697  		return it.
   698  			efficientAddOfLargeItems(
   699  				largeStringsCollection,
   700  				onComplete)
   701  	}
   702  
   703  	wg := &sync.WaitGroup{}
   704  	wg.Add(length)
   705  
   706  	for _, item := range *largeStringsCollection {
   707  		foundCollection := it.GetCollectionLock(
   708  			item,
   709  			true)
   710  
   711  		go foundCollection.AddWithWgLock(
   712  			item,
   713  			wg,
   714  		)
   715  	}
   716  
   717  	wg.Wait()
   718  
   719  	if onComplete != nil {
   720  		onComplete(it)
   721  	}
   722  
   723  	return it
   724  }
   725  
   726  func (it *CharCollectionMap) efficientAddOfLargeItems(
   727  	largeStringsCollection *[]string,
   728  	onComplete OnCompleteCharCollectionMap,
   729  ) *CharCollectionMap {
   730  	allCharsMap := it.
   731  		GetCharsPtrGroups(largeStringsCollection)
   732  
   733  	wg := &sync.WaitGroup{}
   734  	wg.Add(allCharsMap.Length())
   735  
   736  	for key, collection := range allCharsMap.items {
   737  		foundCollection := it.GetCollectionLock(
   738  			string(key),
   739  			true)
   740  
   741  		go foundCollection.AddStringsPtrWgLock(
   742  			&collection.items,
   743  			wg,
   744  		)
   745  	}
   746  
   747  	wg.Wait()
   748  
   749  	if onComplete != nil {
   750  		onComplete(it)
   751  	}
   752  
   753  	return it
   754  }
   755  
   756  func (it *CharCollectionMap) AddStringsPtr(
   757  	items *[]string,
   758  ) *CharCollectionMap {
   759  	if items == nil ||
   760  		*items == nil ||
   761  		len(*items) == 0 {
   762  		return it
   763  	}
   764  
   765  	for _, item := range *items {
   766  		itemC := item
   767  		it.AddStringPtr(&itemC)
   768  	}
   769  
   770  	return it
   771  }
   772  
   773  func (it *CharCollectionMap) AddStrings(
   774  	items ...string,
   775  ) *CharCollectionMap {
   776  	if len(items) == 0 {
   777  		return it
   778  	}
   779  
   780  	for i := range items {
   781  		it.AddStringPtr(&(items)[i])
   782  	}
   783  
   784  	return it
   785  }
   786  
   787  func (it *CharCollectionMap) GetCollection(
   788  	strFirstChar string,
   789  	isAddNewOnEmpty bool,
   790  ) *Collection {
   791  	char := it.GetChar(strFirstChar)
   792  
   793  	collection, has := it.items[char]
   794  
   795  	if has {
   796  		return collection
   797  	}
   798  
   799  	if isAddNewOnEmpty {
   800  		newCollection := New.Collection.Cap(it.eachCollectionCapacity)
   801  		it.items[char] = newCollection
   802  
   803  		return newCollection
   804  	}
   805  
   806  	return nil
   807  }
   808  
   809  func (it *CharCollectionMap) GetCollectionLock(
   810  	strFirstChar string,
   811  	isAddNewOnEmpty bool,
   812  ) *Collection {
   813  	it.Lock()
   814  	defer it.Unlock()
   815  
   816  	return it.GetCollection(
   817  		strFirstChar,
   818  		isAddNewOnEmpty)
   819  }
   820  
   821  func (it *CharCollectionMap) AddSameCharsCollection(
   822  	str string,
   823  	stringsWithSameStartChar *Collection,
   824  ) *Collection {
   825  	isNilOrEmptyCollectionGiven := stringsWithSameStartChar == nil ||
   826  		stringsWithSameStartChar.IsEmpty()
   827  
   828  	foundCollection := it.GetCollection(
   829  		str,
   830  		false)
   831  
   832  	has := foundCollection != nil
   833  	isAddToCollection := has && !isNilOrEmptyCollectionGiven
   834  	hasCollectionHoweverNothingToAdd := has && isNilOrEmptyCollectionGiven
   835  
   836  	if isAddToCollection {
   837  		//goland:noinspection GoNilness
   838  		foundCollection.AddStringsPtr(
   839  			&stringsWithSameStartChar.items)
   840  
   841  		return foundCollection
   842  	} else if hasCollectionHoweverNothingToAdd {
   843  		return foundCollection
   844  	}
   845  
   846  	char := it.GetChar(str)
   847  
   848  	if isNilOrEmptyCollectionGiven {
   849  		// create new
   850  		newCollection := New.Collection.Cap(
   851  			it.eachCollectionCapacity)
   852  		it.items[char] = newCollection
   853  
   854  		return newCollection
   855  	}
   856  
   857  	// items exist or stringsWithSameStartChar exists
   858  	it.items[char] =
   859  		stringsWithSameStartChar
   860  
   861  	return stringsWithSameStartChar
   862  }
   863  
   864  func (it *CharCollectionMap) AddCollectionItems(
   865  	collectionWithDiffStarts *Collection,
   866  ) *CharCollectionMap {
   867  	if collectionWithDiffStarts == nil ||
   868  		collectionWithDiffStarts.IsEmpty() {
   869  		return it
   870  	}
   871  
   872  	it.AddStringsPtr(
   873  		&collectionWithDiffStarts.items)
   874  
   875  	return it
   876  }
   877  
   878  func (it *CharCollectionMap) AddCharHashsetMap(
   879  	charHashsetMap *CharHashsetMap,
   880  ) *CharCollectionMap {
   881  	if charHashsetMap.IsEmpty() {
   882  		return it
   883  	}
   884  
   885  	for _, hashset := range charHashsetMap.items {
   886  		for item := range hashset.items {
   887  			it.Add(item)
   888  		}
   889  	}
   890  
   891  	return it
   892  }
   893  
   894  func (it *CharCollectionMap) Resize(
   895  	newLength int,
   896  ) *CharCollectionMap {
   897  	currentLength := it.Length()
   898  
   899  	if currentLength >= newLength {
   900  		return it
   901  	}
   902  
   903  	newCollection := make(map[byte]*Collection, newLength)
   904  
   905  	for key, element := range it.items {
   906  		newCollection[key] = element
   907  	}
   908  
   909  	it.items = nil
   910  	it.items = newCollection
   911  
   912  	return it
   913  }
   914  
   915  func (it *CharCollectionMap) AddLength(
   916  	lengths ...int,
   917  ) *CharCollectionMap {
   918  	if len(lengths) == 0 {
   919  		return it
   920  	}
   921  
   922  	currentLength := it.Length()
   923  
   924  	for _, capacity := range lengths {
   925  		currentLength += capacity
   926  	}
   927  
   928  	return it.Resize(currentLength)
   929  }
   930  
   931  func (it *CharCollectionMap) AddCollectionItemsAsyncLock(
   932  	collectionWithDiffStarts *Collection,
   933  	onComplete OnCompleteCharCollectionMap,
   934  ) *CharCollectionMap {
   935  	if collectionWithDiffStarts == nil ||
   936  		collectionWithDiffStarts.IsEmpty() {
   937  		return it
   938  	}
   939  
   940  	go it.AddStringsPtrAsyncLock(
   941  		&collectionWithDiffStarts.items,
   942  		onComplete)
   943  
   944  	return it
   945  }
   946  
   947  func (it *CharCollectionMap) List() *[]string {
   948  	if it == nil ||
   949  		it.IsEmpty() {
   950  		return constants.EmptyStringsPtr
   951  	}
   952  
   953  	list := make([]string, it.AllLengthsSum())
   954  
   955  	i := 0
   956  	for _, collection := range it.items {
   957  		for _, itemInList := range collection.items {
   958  			list[i] = itemInList
   959  			i++
   960  		}
   961  	}
   962  
   963  	return &list
   964  }
   965  
   966  func (it *CharCollectionMap) ListLock() *[]string {
   967  	it.Lock()
   968  	defer it.Unlock()
   969  
   970  	return it.List()
   971  }
   972  
   973  func (it *CharCollectionMap) AddSameCharsCollectionLock(
   974  	str string,
   975  	stringsWithSameStartChar *Collection,
   976  ) *Collection {
   977  	isNilOrEmptyCollectionGiven := stringsWithSameStartChar == nil ||
   978  		stringsWithSameStartChar.IsEmpty()
   979  
   980  	foundCollection := it.GetCollectionLock(
   981  		str,
   982  		false)
   983  	has := foundCollection != nil
   984  	isAddToCollection := has && !isNilOrEmptyCollectionGiven
   985  	hasCollectionHoweverNothingToAdd := has && isNilOrEmptyCollectionGiven
   986  
   987  	if isAddToCollection {
   988  		//goland:noinspection GoNilness
   989  		foundCollection.AddStringsPtrLock(&stringsWithSameStartChar.items)
   990  
   991  		return foundCollection
   992  	} else if hasCollectionHoweverNothingToAdd {
   993  		return foundCollection
   994  	}
   995  
   996  	char := it.GetChar(str)
   997  
   998  	if isNilOrEmptyCollectionGiven {
   999  		// create new
  1000  		newCollection := New.Collection.Cap(
  1001  			it.eachCollectionCapacity)
  1002  
  1003  		it.Lock()
  1004  
  1005  		it.items[char] = newCollection
  1006  
  1007  		it.Unlock()
  1008  
  1009  		return newCollection
  1010  	}
  1011  
  1012  	// items exist or stringsWithSameStartChar exists
  1013  	it.Lock()
  1014  	it.items[char] =
  1015  		stringsWithSameStartChar
  1016  	it.Unlock()
  1017  
  1018  	return stringsWithSameStartChar
  1019  }
  1020  
  1021  func (it *CharCollectionMap) GetCollectionByChar(
  1022  	char byte,
  1023  ) *Collection {
  1024  	return it.items[char]
  1025  }
  1026  
  1027  func (it *CharCollectionMap) HashsetByChar(
  1028  	char byte,
  1029  ) *Hashset {
  1030  	collection, has := it.items[char]
  1031  
  1032  	if !has {
  1033  		return nil
  1034  	}
  1035  
  1036  	return New.Hashset.UsingCollection(
  1037  		collection)
  1038  }
  1039  
  1040  func (it *CharCollectionMap) HashsetByCharLock(
  1041  	char byte,
  1042  ) *Hashset {
  1043  	it.Lock()
  1044  	collection := it.items[char]
  1045  	it.Unlock()
  1046  
  1047  	if collection == nil {
  1048  		return New.Hashset.Empty()
  1049  	}
  1050  
  1051  	items := collection.ListCopyPtrLock()
  1052  
  1053  	return New.Hashset.Strings(
  1054  		items,
  1055  	)
  1056  }
  1057  
  1058  func (it *CharCollectionMap) HashsetByStringFirstChar(
  1059  	str string,
  1060  ) *Hashset {
  1061  	char := it.GetChar(str)
  1062  
  1063  	return it.HashsetByChar(char)
  1064  }
  1065  
  1066  func (it *CharCollectionMap) HashsetByStringFirstCharLock(
  1067  	str string,
  1068  ) *Hashset {
  1069  	char := it.GetChar(str)
  1070  
  1071  	return it.HashsetByCharLock(char)
  1072  }
  1073  
  1074  func (it *CharCollectionMap) HashsetsCollectionByStringFirstChar(
  1075  	stringItems ...string,
  1076  ) *HashsetsCollection {
  1077  	if it.IsEmpty() {
  1078  		return Empty.HashsetsCollection()
  1079  	}
  1080  
  1081  	hashsets := make(
  1082  		[]*Hashset,
  1083  		0,
  1084  		it.Length())
  1085  
  1086  	for _, item := range stringItems {
  1087  		char := it.GetChar(item)
  1088  		hashset := it.HashsetByChar(char)
  1089  		if hashset == nil || hashset.IsEmpty() {
  1090  			continue
  1091  		}
  1092  
  1093  		hashsets = append(hashsets, hashset)
  1094  	}
  1095  
  1096  	return New.HashsetsCollection.UsingHashsetsPointers(hashsets...)
  1097  }
  1098  
  1099  func (it *CharCollectionMap) HashsetsCollection() *HashsetsCollection {
  1100  	if it.IsEmpty() {
  1101  		return Empty.HashsetsCollection()
  1102  	}
  1103  
  1104  	hashsets := make(
  1105  		[]*Hashset,
  1106  		0,
  1107  		it.Length())
  1108  
  1109  	for _, collection := range it.items {
  1110  		if collection == nil ||
  1111  			collection.IsEmpty() {
  1112  			continue
  1113  		}
  1114  
  1115  		hashset := collection.HashsetAsIs()
  1116  		hashsets = append(hashsets, hashset)
  1117  	}
  1118  
  1119  	return New.HashsetsCollection.UsingHashsetsPointers(hashsets...)
  1120  }
  1121  
  1122  func (it *CharCollectionMap) HashsetsCollectionByChars(
  1123  	chars ...byte,
  1124  ) *HashsetsCollection {
  1125  	if it.IsEmpty() {
  1126  		return Empty.HashsetsCollection()
  1127  	}
  1128  
  1129  	hashsets := make(
  1130  		[]*Hashset,
  1131  		0,
  1132  		it.Length())
  1133  
  1134  	for _, char := range chars {
  1135  		hashset := it.HashsetByChar(char)
  1136  		if hashset == nil ||
  1137  			hashset.IsEmpty() {
  1138  			continue
  1139  		}
  1140  
  1141  		hashsets = append(hashsets, hashset)
  1142  	}
  1143  
  1144  	return New.HashsetsCollection.UsingHashsetsPointers(hashsets...)
  1145  }
  1146  
  1147  func (it *CharCollectionMap) JsonModel() *CharCollectionDataModel {
  1148  	return &CharCollectionDataModel{
  1149  		Items: it.items,
  1150  		EachCollectionCapacity: it.
  1151  			eachCollectionCapacity,
  1152  	}
  1153  }
  1154  
  1155  func (it *CharCollectionMap) JsonModelAny() interface{} {
  1156  	return it.JsonModel()
  1157  }
  1158  
  1159  func (it *CharCollectionMap) AsJsonContractsBinder() corejson.JsonContractsBinder {
  1160  	return it
  1161  }
  1162  
  1163  func (it *CharCollectionMap) AsJsoner() corejson.Jsoner {
  1164  	return it
  1165  }
  1166  
  1167  func (it *CharCollectionMap) AsJsonMarshaller() corejson.JsonMarshaller {
  1168  	return it
  1169  }
  1170  
  1171  func (it *CharCollectionMap) AsJsonParseSelfInjector() corejson.JsonParseSelfInjector {
  1172  	return it
  1173  }
  1174  
  1175  func (it *CharCollectionMap) JsonParseSelfInject(
  1176  	jsonResult *corejson.Result,
  1177  ) error {
  1178  	_, err := it.ParseInjectUsingJson(
  1179  		jsonResult,
  1180  	)
  1181  
  1182  	return err
  1183  }
  1184  
  1185  func (it *CharCollectionMap) MarshalJSON() ([]byte, error) {
  1186  	return json.Marshal(*it.JsonModel())
  1187  }
  1188  
  1189  func (it *CharCollectionMap) UnmarshalJSON(data []byte) error {
  1190  	var dataModel CharCollectionDataModel
  1191  
  1192  	err := json.Unmarshal(data, &dataModel)
  1193  
  1194  	if err == nil {
  1195  		it.items = dataModel.Items
  1196  		it.eachCollectionCapacity =
  1197  			dataModel.EachCollectionCapacity
  1198  	}
  1199  
  1200  	return err
  1201  }
  1202  
  1203  func (it CharCollectionMap) Json() corejson.Result {
  1204  	return corejson.New(it)
  1205  }
  1206  
  1207  func (it CharCollectionMap) JsonPtr() *corejson.Result {
  1208  	return corejson.NewPtr(it)
  1209  }
  1210  
  1211  func (it *CharCollectionMap) ParseInjectUsingJson(
  1212  	jsonResult *corejson.Result,
  1213  ) (*CharCollectionMap, error) {
  1214  	err := jsonResult.Unmarshal(it)
  1215  
  1216  	if err != nil {
  1217  		return Empty.CharCollectionMap(), err
  1218  	}
  1219  
  1220  	return it, nil
  1221  }
  1222  
  1223  // ParseInjectUsingJsonMust Panic if error
  1224  func (it *CharCollectionMap) ParseInjectUsingJsonMust(
  1225  	jsonResult *corejson.Result,
  1226  ) *CharCollectionMap {
  1227  	newUsingJson, err :=
  1228  		it.ParseInjectUsingJson(jsonResult)
  1229  
  1230  	if err != nil {
  1231  		panic(err)
  1232  	}
  1233  
  1234  	return newUsingJson
  1235  }
  1236  
  1237  // Clear clears existing items, deletes items using delete(*charCollectionMap.items, char)
  1238  func (it *CharCollectionMap) Clear() *CharCollectionMap {
  1239  	if it.IsEmpty() {
  1240  		return it
  1241  	}
  1242  
  1243  	for char, values := range it.items {
  1244  		values.Dispose()
  1245  		values = nil
  1246  
  1247  		delete(it.items, char)
  1248  	}
  1249  
  1250  	return it
  1251  }
  1252  
  1253  func (it *CharCollectionMap) Dispose() {
  1254  	if it == nil {
  1255  		return
  1256  	}
  1257  
  1258  	it.Clear()
  1259  	it.items = nil
  1260  }