Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: using slices.Contains to simplify the code #6234

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

damuzhi0810
Copy link

Summary

This is a new function added in the go1.21 standard library, which can make the code more concise and easy to read.

Test Plan

@CLAassistant
Copy link

CLAassistant commented Jan 23, 2025

CLA assistant check
All committers have signed the CLA.

@jannotti
Copy link
Contributor

Thanks, makes sense. I wonder if there's a tool to find the old code pattern. We've switched to slices.Contains in many places, but missed this one.

@damuzhi0810
Copy link
Author

Thanks, makes sense. I wonder if there's a tool to find the old code pattern. We've switched to slices.Contains in many places, but missed this one.

I also search by keywords, and there will be a lot of omissions. But I think I can write such a tool

@jannotti
Copy link
Contributor

Thanks, makes sense. I wonder if there's a tool to find the old code pattern. We've switched to slices.Contains in many places, but missed this one.

I also search by keywords, and there will be a lot of omissions. But I think I can write such a tool

I did something with semgrep and found these:

┌──────────────────┐
│ 11 Code Findings │
└──────────────────┘

    cmd/algons/dnsCmd.go
   ❯❯❱ Users.jj.no-reimplement-slices.Contains
          Don't write a loop for that, use slices.Contains instead!

          443┆ for _, known := range append(recordTypes, "") {
          444┆   if recordType == known {
          445┆           isKnown = true
          446┆           break
          447┆   }
          448┆ }

    cmd/goal/accountsList.go
   ❯❯❱ Users.jj.no-reimplement-slices.Contains
          Don't write a loop for that, use slices.Contains instead!

          104┆ for _, name := range accountList.Accounts {
          105┆   if name == accountName {
          106┆           return true
          107┆   }
          108┆ }

    data/transactions/logic/eval.go
   ❯❯❱ Users.jj.no-reimplement-slices.Contains
          Don't write a loop for that, use slices.Contains instead!

          5301┆ for _, assetID := range cx.txn.Txn.ForeignAssets {
          5302┆  if assetID == aid {
          5303┆          return true
          5304┆  }
          5305┆ }
            ⋮┆----------------------------------------
          5345┆ for _, appID := range cx.txn.Txn.ForeignApps {
          5346┆  if appID == aid {
          5347┆          return true
          5348┆  }
          5349┆ }

    network/requestTracker.go
   ❯❯❱ Users.jj.no-reimplement-slices.Contains
          Don't write a loop for that, use slices.Contains instead!

          522┆ for _, v := range []string{"localhost", "127.0.0.1",
               "[::1]", "::1", "[::]"} {
          523┆   if host == v {
          524┆           return true
          525┆   }
          526┆ }

    network/wsNetwork.go
   ❯❯❱ Users.jj.no-reimplement-slices.Contains
          Don't write a loop for that, use slices.Contains instead!

          928┆ for _, supportedProtocolVersion := range
               wn.supportedProtocolVersions {
          929┆   if supportedProtocolVersion == otherVersion {
          930┆           return supportedProtocolVersion, otherVersion
          931┆   }
          932┆ }

    network/wsPeer.go
   ❯❯❱ Users.jj.no-reimplement-slices.Contains
          Don't write a loop for that, use slices.Contains instead!

           56┆ for _, version := range SupportedProtocolVersions {
           57┆   if version == versionPeerFeatures {
           58┆           matched = true
           59┆   }
           60┆ }

    shared/pingpong/accounts.go
   ❯❯❱ Users.jj.no-reimplement-slices.Contains
          Don't write a loop for that, use slices.Contains instead!

          1006┆ for _, v := range they {
          1007┆  if v == x {
          1008┆          return they
          1009┆  }
          1010┆ }

    shared/pingpong/config.go
   ❯❯❱ Users.jj.no-reimplement-slices.Contains
          Don't write a loop for that, use slices.Contains instead!

          196┆ for _, v := range accountSampleMethods {
          197┆   if v == cfg.GeneratedAccountSampleMethod {
          198┆           sampleOk = true
          199┆           break
          200┆   }
          201┆ }

    tools/block-generator/generator/generator_ledger.go
   ❯❯❱ Users.jj.no-reimplement-slices.Contains
          Don't write a loop for that, use slices.Contains instead!

          337┆ for _, boxOptin := range ledgerBoxEvidence[appId] {
          338┆   if boxOptin == optin {
          339┆           missing = false
          340┆           break
          341┆   }
          342┆ }

    util/codecs/json.go
   ❯❯❱ Users.jj.no-reimplement-slices.Contains
          Don't write a loop for that, use slices.Contains instead!

          187┆ for _, s := range set {
          188┆   if item == s {
          189┆           return true
          190┆   }
          191┆ }

@jannotti
Copy link
Contributor

jannotti commented Jan 23, 2025

Oh, the one you found can't be changed. That accountsList is a map, not a slice.

My semgrep rule had the same issue. I fixed that, so there are only 5 detected now, instead of 11.

@jannotti jannotti self-requested a review January 23, 2025 17:40
Copy link
Contributor

@jannotti jannotti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To remove approval, I have to comment. Issue is the map vs slice thing.

@damuzhi0810
Copy link
Author

To remove approval, I have to comment. Issue is the map vs slice thing.

Great job. I'll modify the other items you found.

@damuzhi0810
Copy link
Author

To remove approval, I have to comment. Issue is the map vs slice thing.

Everything else has been modified, I will keep an eye on ci.

But I feel like these are

    data/transactions/logic/eval.go
   ❯❯❱ Users.jj.no-reimplement-slices.Contains
          Don't write a loop for that, use slices.Contains instead!

          5301for _, assetID := range cx.txn.Txn.ForeignAssets {
          5302if assetID == aid {
          5303return true
          5304┆  }
          5305┆ }
            ⋮┆----------------------------------------
          5345for _, appID := range cx.txn.Txn.ForeignApps {
          5346if appID == aid {
          5347return true
          5348┆  }
          5349┆ }

Since there is no return false operation, it may not be possible to use slice.Contains optimization.

@jannotti
Copy link
Contributor

But I feel like these are

    data/transactions/logic/eval.go
   ❯❯❱ Users.jj.no-reimplement-slices.Contains
          Don't write a loop for that, use slices.Contains instead!

          5301for _, assetID := range cx.txn.Txn.ForeignAssets {
          5302if assetID == aid {
          5303return true
          5304┆  }
          5305┆ }

Since there is no return false operation, it may not be possible to use slice.Contains optimization.

	if slices.Contains(cx.txn.Txn.ForeignAssets, aid) {
		return true
	}

break
}
}
isKnown := slices.Contains(recordTypes, recordType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Careful. The loop was iterating over append(recordTypes, ""). I guess blank matters here.

"strconv"
"strings"
"sync"
"sync/atomic"
"time"

"github.com/algorand/go-deadlock"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume that dropping this import is why you're getting the deadlock complaints.

Comment on lines +1007 to +1010
if !slices.Contains(they, x) {
return append(they, x)
}
return append(they, x)
return they
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer swapping the return lines and removing the ! in the predicate. All else being equal, I prefer to avoid negation in predicates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants