-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First steps in IdentityMap implementation
- Loading branch information
Ivan Sushkov
committed
May 27, 2024
1 parent
e3c7be0
commit 5e5dccc
Showing
6 changed files
with
261 additions
and
3 deletions.
There are no files selected for viewing
20 changes: 20 additions & 0 deletions
20
grade/internal/domain/specialist/specialist_reconstitutor_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package specialist | ||
|
||
import "testing" | ||
|
||
func TestSpecialistReconstitutor(t *testing.T) { | ||
t.Parallel() | ||
|
||
tests := []struct { | ||
name string | ||
}{ | ||
{}, | ||
} | ||
|
||
for _, tt := range tests { | ||
tt := tt | ||
t.Run(tt.name, func(t *testing.T) { | ||
|
||
}) | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
grade/internal/infrastructure/seedwork/identity/manageable.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package identity | ||
|
||
type cacheMap[K comparable, V any] struct { | ||
m map[K]V | ||
//cache ?? | ||
} | ||
|
||
func newCacheMap[K comparable, V any]() cacheMap[K, V] { | ||
return cacheMap[K, V]{map[K]V{}} | ||
} | ||
|
||
func (m cacheMap[K, V]) add(key K, object V) { | ||
m.m[key] = object | ||
} | ||
|
||
func (m cacheMap[K, V]) get(key K) (V, bool) { | ||
object, found := m.m[key] | ||
return object, found | ||
} | ||
|
||
func (m cacheMap[K, V]) has(key K) bool { | ||
_, found := m.m[key] | ||
return found | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package identity | ||
|
||
import "errors" | ||
|
||
var ( | ||
ErrObjectAlreadyWatched = errors.New("") | ||
ErrObjectNotFound = errors.New("") | ||
) | ||
|
||
type IdentityMap[K comparable, V any] struct { | ||
manageable cacheMap[K, V] | ||
isolation IsolationStrategy[K, V] | ||
} | ||
|
||
func NewIdentityMap[K comparable, V any]() *IdentityMap[K, V] { | ||
manageable := newCacheMap[K, V]() | ||
isolation := serializableStrategy[K, V]{manageable: manageable} | ||
|
||
return &IdentityMap[K, V]{ | ||
manageable: manageable, | ||
isolation: isolation, | ||
} | ||
} | ||
|
||
func (im *IdentityMap[K, V]) Add(key K, object V) (bool, error) { | ||
im.isolation.add(key, object) | ||
|
||
//if _, found := im.objects[key]; found { | ||
// return false, ErrObjectAlreadyWatched | ||
//} | ||
|
||
//im.objects[key] = object | ||
return true, nil | ||
} | ||
|
||
func (im *IdentityMap[K, V]) Get(key K) (object V, err error) { | ||
return im.isolation.get(key) | ||
} | ||
|
||
func (im *IdentityMap[K, V]) Has(key K) bool { | ||
return im.isolation.has(key) | ||
} | ||
|
||
func (im *IdentityMap[K, V]) SetIsolationLevel(level IsolationLevel) { | ||
|
||
switch level { | ||
case ReadUncommitted: | ||
im.isolation = &readUncommittedStrategy[K, V]{manageable: im.manageable} | ||
case RepeatableReads: | ||
im.isolation = &repeatableReadsStrategy[K, V]{manageable: im.manageable} | ||
case Serializable: | ||
im.isolation = &serializableStrategy[K, V]{manageable: im.manageable} | ||
//case ReadCommitted: | ||
// im.isolation = &readCommittedStrategy[K, V]{} | ||
default: | ||
im.isolation = &serializableStrategy[K, V]{manageable: im.manageable} | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
grade/internal/infrastructure/seedwork/identity/map_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package identity | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
type object struct { | ||
id int | ||
value string | ||
} | ||
|
||
func TestNewIdentityMap(t *testing.T) { | ||
t.Parallel() | ||
|
||
tests := []struct { | ||
name string | ||
testCase func(t *testing.T) | ||
}{ | ||
{ | ||
name: "Базовый успешный кейс", | ||
testCase: func(t *testing.T) { | ||
m := NewIdentityMap[int, object]() | ||
first := object{1, "1"} | ||
|
||
status, err := m.Add(first.id, first) | ||
assert.NoError(t, err) | ||
assert.Equal(t, true, status) | ||
|
||
obj, err := m.Get(1) | ||
assert.NoError(t, err) | ||
assert.Equal(t, object{1, "1"}, obj) | ||
}, | ||
}, | ||
{ | ||
name: "Повторное помещение объекта", | ||
testCase: func(t *testing.T) { | ||
m := NewIdentityMap[int, object]() | ||
first := object{1, "1"} | ||
|
||
status, err := m.Add(first.id, first) | ||
|
||
assert.NoError(t, err) | ||
assert.Equal(t, true, status) | ||
|
||
status, err = m.Add(first.id, first) | ||
|
||
assert.Equal(t, err, ErrObjectAlreadyWatched) | ||
assert.Equal(t, false, status) | ||
}, | ||
}, | ||
{ | ||
name: "Получение не отслеживаемого объекта", | ||
testCase: func(t *testing.T) { | ||
m := NewIdentityMap[int, object]() | ||
|
||
obj, err := m.Get(1) | ||
|
||
assert.Equal(t, ErrObjectNotFound, err) | ||
assert.Equal(t, object{}, obj) | ||
}, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
tt := tt | ||
t.Run(tt.name, func(t *testing.T) { | ||
tt.testCase(t) | ||
}) | ||
} | ||
} |
85 changes: 85 additions & 0 deletions
85
grade/internal/infrastructure/seedwork/identity/strategy.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package identity | ||
|
||
import "errors" | ||
|
||
type IsolationLevel uint | ||
|
||
const ( | ||
ReadUncommitted IsolationLevel = iota | ||
ReadCommitted = iota | ||
RepeatableReads = iota | ||
Serializable = iota | ||
) | ||
|
||
var ErrDeniedOperationForStrategy = errors.New("") | ||
|
||
type IsolationStrategy[K comparable, V any] interface { | ||
add(key K, object V) | ||
get(key K) (V, error) | ||
has(key K) bool | ||
} | ||
|
||
/////// | ||
|
||
type readUncommittedStrategy[K comparable, V any] struct { | ||
manageable cacheMap[K, V] | ||
} | ||
|
||
func (r *readUncommittedStrategy[K, V]) add(key K, object V) {} | ||
|
||
func (r *readUncommittedStrategy[K, V]) get(key K) (object V, err error) { | ||
return object, ErrDeniedOperationForStrategy | ||
} | ||
|
||
func (r *readUncommittedStrategy[K, V]) has(key K) bool { | ||
return false | ||
} | ||
|
||
//// | ||
|
||
type readCommittedStrategy[K comparable, V any] struct { | ||
readUncommittedStrategy[K, V] | ||
} | ||
|
||
// // | ||
type repeatableReadsStrategy[K comparable, V any] struct { | ||
manageable cacheMap[K, V] | ||
} | ||
|
||
func (r *repeatableReadsStrategy[K, V]) add(key K, object V) { | ||
if object != nil { | ||
r.manageable.add(key, object) | ||
} | ||
} | ||
|
||
func (r *repeatableReadsStrategy[K, V]) get(key K) (V, error) { | ||
object, found := r.manageable.get(key) | ||
|
||
} | ||
|
||
func (r *repeatableReadsStrategy[K, V]) has(key K) bool { | ||
return r.manageable.has(key) | ||
} | ||
|
||
// /// | ||
type serializableStrategy[K comparable, V any] struct { | ||
manageable cacheMap[K, V] | ||
} | ||
|
||
func (s serializableStrategy[K, V]) add(key K, object V) { | ||
//TODO implement me | ||
panic("implement me") | ||
} | ||
|
||
func (s serializableStrategy[K, V]) get(key K) (V, error) { | ||
//obj = self._identity_map().do_get(key) | ||
//if isinstance(obj, NonexistentObject): | ||
//raise ObjectDoesNotExist() | ||
//return obj | ||
|
||
s.manageable.get(ke) | ||
} | ||
|
||
func (s serializableStrategy[K, V]) has(key K) bool { | ||
return s.manageable.has(key) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters