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

updating project organization #3

Merged
merged 4 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/basic/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func main() {
// The contextkey is a string that is used to store and retrieve values from context
// it should be unique to your application
contextKey := "my-unique-context-key"
m := pectx.NewManager(contextKey, &pectx.Store{})
m := pectx.NewManager(contextKey)

ctx := context.Background()

Expand Down
3 changes: 2 additions & 1 deletion examples/duplicates/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"context"
"fmt"

pectx "github.com/pragmaticengineering/pectx"
)

Expand All @@ -11,7 +12,7 @@ func main() {
// The contextkey is a string that is used to store and retrieve values from context
// it should be unique to your application
contextKey := "my-unique-context-key"
m := pectx.NewManager(contextKey, &pectx.Store{})
m := pectx.NewManager(contextKey)

ctx := context.Background()

Expand Down
41 changes: 37 additions & 4 deletions manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,32 @@ package pectx

import (
"context"

mapStore "github.com/pragmaticengineering/pectx/stores/map"
)

// Store is an interface that defines the methods to store and retrieve data from a Store.
type KVStore interface {
KVGetter
KVSetter
}

// KVGetter is an interface that defines the method to retrieve data from a Store.
type KVGetter interface {
Get(key string) (value string)
ListKeys() []string
}

// KVSetter is an interface that defines the method to store data in a Store.
type KVSetter interface {
Set(key string, value string)
}

type ctxKey string

// ManagerOption is a function that sets some option on the manager.
type ManagerOption func(*Manager)

type Manager struct {
// The context key used to store the data in the context.
// This is to avoid collisions with other packages.
Expand All @@ -14,12 +36,24 @@ type Manager struct {
store KVStore
}

// WithStore changes the store used by the manager.
func WithStore(store KVStore) ManagerOption {
return func(m *Manager) {
m.store = store
}
}

// NewManager creates a new manager with the given context key.
func NewManager(uniqueKey string, store KVStore) *Manager {
return &Manager{
func NewManager(uniqueKey string, opts ...ManagerOption) *Manager {
m := &Manager{
ctxKey: ctxKey(uniqueKey),
store: store,
store: &mapStore.Map{},
}
for _, opt := range opts {
opt(m)
}

return m
}

// Get retrieves the values from the context.
Expand Down Expand Up @@ -51,7 +85,6 @@ func (m *Manager) Set(ctx context.Context, keyValues map[string]string) context.
// GetKeysAndValues retrieves the keys and values from the context.
// if the context is empty, it returns an empty slice.
func (m *Manager) GetKeysAndValues(ctx context.Context) []string {

fields, ok := m.Get(ctx)
if !ok {
return []string{}
Expand Down
163 changes: 163 additions & 0 deletions manager_benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package pectx_test

import (
"context"
"fmt"
"testing"

"github.com/pragmaticengineering/pectx"
)

func helperFields(amount int) map[string]string {

store := map[string]string{}
for i := 0; i < amount; i++ {
key := fmt.Sprintf("k%d", i)
store[key] = fmt.Sprintf("v%d", i)

}
return store
}

func BenchmarkManager_Set(b *testing.B) {
var contextKey = "test123123123"

testCases := []struct {
name string
fields map[string]string
mgr *pectx.Manager
ctx context.Context
}{
{
name: "manager with 1 field",
fields: helperFields(1),
mgr: pectx.NewManager(contextKey),
ctx: context.Background(),
},
{
name: "manager with 10 fields",
fields: helperFields(10),
mgr: pectx.NewManager(contextKey),
ctx: context.Background(),
},
{
name: "manager with 100 fields",
fields: helperFields(100),
mgr: pectx.NewManager(contextKey),
ctx: context.Background(),
},
}

for _, tc := range testCases {
b.Run(tc.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
tc.mgr.Set(tc.ctx, tc.fields)
}
})
}
}

func helperFieldsGet(amount int) (context.Context, *pectx.Manager) {
ctx := context.Background()
m := pectx.NewManager(contextKey)

m.Set(ctx, helperFields(amount))

return ctx, m
}

func BenchmarkManager_Get(b *testing.B) {
testCases := []struct {
name string
amount int
}{
{
name: "context with 1 field",
amount: 1,
},
{
name: "context with 10 fields",
amount: 10,
},
{
name: "context with 100 fields",
amount: 100,
},
}

for _, tc := range testCases {
b.Run(tc.name, func(b *testing.B) {
ctx, m := helperFieldsGet(tc.amount)
b.ResetTimer()
for i := 0; i < b.N; i++ {
m.Get(ctx)
}
})
}
}

func BenchmarkManager_GetKeysAndValues(b *testing.B) {
testCases := []struct {
name string
amount int
}{
{
name: "context with 1 field",
amount: 1,
},
{
name: "context with 10 fields",
amount: 10,
},
{
name: "context with 100 fields",
amount: 100,
},
}

for _, tc := range testCases {
b.Run(tc.name, func(b *testing.B) {
ctx, m := helperFieldsGet(tc.amount)
b.ResetTimer()
for i := 0; i < b.N; i++ {
m.GetKeysAndValues(ctx)
}
})
}
}

func BenchmarkKeysAndValues_forloop(b *testing.B) {
manager := pectx.NewManager(contextKey)

// Define test cases
testCases := []struct {
name string
data map[string]string
}{
{
name: "Set 1 key-value pair",
data: map[string]string{
"key1": "value1",
},
},
{
name: "Set 10 key-value pairs",
data: helperFields(10),
},
{
name: "Set 100 key-value pairs",
data: helperFields(100),
},
}

for _, tc := range testCases {
testcase := tc
b.Run(testcase.name, func(b *testing.B) {
ctx := manager.Set(context.Background(), testcase.data)
b.ResetTimer()
for i := 0; i < b.N; i++ {
manager.GetKeysAndValues(ctx)
}
})
}
}
Loading
Loading