( tx *types.CreateDatabase, user proto.AccountAddress, minerCount int)
| 693 | } |
| 694 | |
| 695 | func (s *metaState) filterNMiners( |
| 696 | tx *types.CreateDatabase, |
| 697 | user proto.AccountAddress, |
| 698 | minerCount int) ( |
| 699 | m MinerInfos, err error, |
| 700 | ) { |
| 701 | // create new merged map |
| 702 | allProviderMap := make(map[proto.AccountAddress]*types.ProviderProfile) |
| 703 | for k, v := range s.readonly.provider { |
| 704 | allProviderMap[k] = v |
| 705 | } |
| 706 | for k, v := range s.dirty.provider { |
| 707 | if v == nil { |
| 708 | delete(allProviderMap, k) |
| 709 | } else { |
| 710 | allProviderMap[k] = v |
| 711 | } |
| 712 | } |
| 713 | |
| 714 | // delete selected target miners |
| 715 | for _, m := range tx.ResourceMeta.TargetMiners { |
| 716 | delete(allProviderMap, m) |
| 717 | } |
| 718 | |
| 719 | // suppose 1/4 miners match |
| 720 | newMiners := make(MinerInfos, 0, len(allProviderMap)/4) |
| 721 | // filter all miners to slice and sort |
| 722 | for _, po := range allProviderMap { |
| 723 | newMiners, _ = filterAndAppendMiner(newMiners, po, tx, user) |
| 724 | } |
| 725 | if newMiners.Len() < minerCount { |
| 726 | err = ErrNoEnoughMiner |
| 727 | return |
| 728 | } |
| 729 | |
| 730 | sort.Slice(newMiners, newMiners.Less) |
| 731 | return newMiners[:minerCount], nil |
| 732 | } |
| 733 | |
| 734 | func filterAndAppendMiner( |
| 735 | miners MinerInfos, |
no test coverage detected