-
Notifications
You must be signed in to change notification settings - Fork 4.1k
fix(collections): add IterateRaw() implementation for Multi index #25123
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -110,3 +110,110 @@ | |||||
require.NoError(t, err) | ||||||
require.Equal(t, []byte{}, rawValue) | ||||||
} | ||||||
|
||||||
func TestMulti_PairPrimaryKey(t *testing.T) { | ||||||
sk, ctx := deps() | ||||||
schema := collections.NewSchemaBuilder(sk) | ||||||
|
||||||
mi := NewMulti(schema, | ||||||
collections.NewPrefix(1), "multi_index", | ||||||
collections.Uint64Key, | ||||||
collections.PairKeyCodec(collections.Uint64Key, collections.Uint64Key), | ||||||
func(pk collections.Pair[uint64, uint64], _ collections.NoValue) (uint64, error) { | ||||||
return pk.K2(), nil | ||||||
}, | ||||||
) | ||||||
|
||||||
// we create two reference keys for primary key 1 and 2 associated with "milan" | ||||||
require.NoError(t, mi.Reference(ctx, collections.Join(uint64(1), uint64(1)), collections.NoValue{}, func() (collections.NoValue, error) { return collections.NoValue{}, collections.ErrNotFound })) | ||||||
require.NoError(t, mi.Reference(ctx, collections.Join(uint64(2), uint64(1)), collections.NoValue{}, func() (collections.NoValue, error) { return collections.NoValue{}, collections.ErrNotFound })) | ||||||
|
||||||
iter, err := mi.MatchExact(ctx, uint64(1)) | ||||||
require.NoError(t, err) | ||||||
pks, err := iter.PrimaryKeys() | ||||||
require.NoError(t, err) | ||||||
expectedPks := []collections.Pair[uint64, uint64]{ | ||||||
collections.Join(uint64(1), uint64(1)), | ||||||
collections.Join(uint64(2), uint64(1)), | ||||||
} | ||||||
require.Equal(t, expectedPks, pks) | ||||||
|
||||||
rawIter, err := mi.IterateRaw(ctx, nil, nil, collections.OrderAscending) | ||||||
require.NoError(t, err) | ||||||
defer iter.Close() | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Closing the wrong iterator (resource leak) Line 143 defers iter.Close(), but the iterator created at Line 141 is rawIter. rawIter is never closed. - defer iter.Close()
+ defer rawIter.Close() 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||
|
||||||
count := 0 | ||||||
for ; rawIter.Valid(); rawIter.Next() { | ||||||
key, err := rawIter.Key() | ||||||
require.NoError(t, err) | ||||||
require.Equal(t, uint64(1), key.K1()) | ||||||
expectedKey := collections.Join(uint64(count+1), uint64(1)) | ||||||
require.Equal(t, expectedKey, key.K2()) | ||||||
count++ | ||||||
} | ||||||
require.Equal(t, 2, count) | ||||||
} | ||||||
Check failure on line 155 in collections/indexes/multi_test.go
|
||||||
func TestMulti_IterateRaw(t *testing.T) { | ||||||
sk, ctx := deps() | ||||||
schema := collections.NewSchemaBuilder(sk) | ||||||
|
||||||
mi := NewMulti(schema, collections.NewPrefix(1), "multi_index", collections.StringKey, collections.Uint64Key, func(_ uint64, value company) (string, error) { | ||||||
return value.City, nil | ||||||
}) | ||||||
|
||||||
// Insert some test data | ||||||
company1 := company{City: "milan"} | ||||||
company2 := company{City: "new york"} | ||||||
company3 := company{City: "milan"} | ||||||
companies := []company{company1, company2, company3} | ||||||
|
||||||
for i, c := range companies { | ||||||
ref := uint64(i) + 1 | ||||||
err := mi.Reference(ctx, ref, c, func() (company, error) { return c, nil }) | ||||||
require.NoError(t, err) | ||||||
} | ||||||
|
||||||
// Test IterateRaw with ascending order | ||||||
iter, err := mi.IterateRaw(ctx, nil, nil, collections.OrderAscending) | ||||||
require.NoError(t, err) | ||||||
defer iter.Close() | ||||||
|
||||||
var count int | ||||||
for ; iter.Valid(); iter.Next() { | ||||||
key, err := iter.Key() | ||||||
require.NoError(t, err) | ||||||
require.NotEmpty(t, key.K1()) | ||||||
require.NotEmpty(t, key.K2()) | ||||||
count++ | ||||||
} | ||||||
require.Equal(t, 3, count) | ||||||
|
||||||
// Test IterateRaw with descending order | ||||||
iter, err = mi.IterateRaw(ctx, nil, nil, collections.OrderDescending) | ||||||
require.NoError(t, err) | ||||||
defer iter.Close() | ||||||
|
||||||
count = 0 | ||||||
for ; iter.Valid(); iter.Next() { | ||||||
key, err := iter.Key() | ||||||
require.NoError(t, err) | ||||||
require.NotEmpty(t, key.K1()) | ||||||
require.NotEmpty(t, key.K2()) | ||||||
count++ | ||||||
} | ||||||
require.Equal(t, 3, count) | ||||||
|
||||||
// Test with specific range - use MatchExact to get the correct keys | ||||||
matchIter, err := mi.MatchExact(ctx, "milan") | ||||||
require.NoError(t, err) | ||||||
defer matchIter.Close() | ||||||
|
||||||
count = 0 | ||||||
for ; matchIter.Valid(); matchIter.Next() { | ||||||
fullKey, err := matchIter.FullKey() | ||||||
require.NoError(t, err) | ||||||
require.Equal(t, "milan", fullKey.K1()) | ||||||
count++ | ||||||
} | ||||||
require.Equal(t, 2, count) | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Ensure iterator from MatchExact is closed
The iterator created at Line 131 isn’t closed. Add a defer right after the error check.
iter, err := mi.MatchExact(ctx, uint64(1)) require.NoError(t, err) +defer iter.Close() pks, err := iter.PrimaryKeys()
📝 Committable suggestion
🤖 Prompt for AI Agents