From 52cfb5e7489ef6000ddca6d293a4a31fab305827 Mon Sep 17 00:00:00 2001 From: pm-aadit-patil <102031086+pm-aadit-patil@users.noreply.github.com> Date: Mon, 11 Jul 2022 19:14:17 +0530 Subject: [PATCH] UOE:7907: Implement keyState data structure (#2) * Added Async Cache in pkg cache with Get and Set methods * UOE-7907:Added KeyStateDS with Operation Functions and Tests Cases * UOE-7907: Renamed state to status, removed get,set and changed test cases according to PR comments * UOE-7907:Changes based on CR and Comments --- async_cache.go | 55 ++++++++++++++++++++ async_cache_test.go | 121 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 async_cache.go create mode 100644 async_cache_test.go diff --git a/async_cache.go b/async_cache.go new file mode 100644 index 0000000..e0effd0 --- /dev/null +++ b/async_cache.go @@ -0,0 +1,55 @@ +package cache + +import ( + "sync" +) + +//status is signal which helps to identify in which state the current process with a specific key is +type status int + +//status for keys/process declared in constants +const ( + STATUS_NOTPRESENT status = iota //current key is not present in KeyMap + STATUS_INPROCESS // current key/process is already INPROCESS to fetch data from data source + STATUS_DONE //current key/process have DONE fetching data and updated in cache + STATUS_STATUS_INTERNAL_ERROR //current key/process recieved internal_error while fetching data + STATUS_INVALID_KEY // current key is invalid to be fetched +) + +type keyStatus struct { + keyMap map[string]status //status{INPROCESS,DONE,INVALID,NOPRESENT,INVALID_KEY} + mu *sync.RWMutex +} + +//To Create A New keyStatus +func NewKeyStatus() *keyStatus { + return &keyStatus{ + keyMap: make(map[string]status), + mu: &sync.RWMutex{}, + } +} + +//Set status/status with respective key in keyStatus +func (ks *keyStatus) Set(key string, status status) { + + if len(key) > 0 { + ks.mu.Lock() + ks.keyMap[key] = status //updating status in keyMap for particular "key" + ks.mu.Unlock() + } +} + +//Get status/status of respective key in keyStatus +func (ks *keyStatus) Get(key string) status { + if len(key) == 0 { + return STATUS_INVALID_KEY + } + ks.mu.RLock() + status, found := ks.keyMap[key] + ks.mu.RUnlock() + if !found { + return STATUS_NOTPRESENT + } + return status + +} diff --git a/async_cache_test.go b/async_cache_test.go new file mode 100644 index 0000000..ba7728e --- /dev/null +++ b/async_cache_test.go @@ -0,0 +1,121 @@ +package cache + +import ( + "sync" + "testing" +) + +func Test_keyStatus_Set(t *testing.T) { + + type fields struct { + keyMap map[string]status + mu *sync.RWMutex + } + type args struct { + key string + status status + } + tests := []struct { + name string + fields fields + args args + wantStatus status + }{ + { + name: "With Valid key and state", + fields: fields(*NewKeyStatus()), + args: args{ + key: "prof_123", + status: STATUS_INPROCESS, + }, + wantStatus: STATUS_INPROCESS, + }, + { + name: "With InValid key and state", + fields: fields(*NewKeyStatus()), + args: args{ + key: "", + status: STATUS_INPROCESS, + }, + wantStatus: STATUS_INVALID_KEY, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + ks := NewKeyStatus() + t.Parallel() + ks.Set(tt.args.key, tt.args.status) + if ks.Get(tt.args.key) != tt.wantStatus { + t.Log(tt.fields.keyMap) + t.Errorf("KeyStatys.Set() sets status %v, want status %v", tt.args.status, tt.wantStatus) + } + }) + } +} + +func Test_keyStatus_Get(t *testing.T) { + + type args struct { + key string + } + tests := []struct { + name string + KeyS keyStatus + args args + want status + }{ + { + name: "With Valid key and state as DONE", + KeyS: func() keyStatus { + ks := NewKeyStatus() + ks.Set("prof_123", STATUS_DONE) + return *ks + }(), + args: args{ + key: "prof_123", + }, + want: STATUS_DONE, + }, + { + name: "With Valid key and state as INPROCESS", + KeyS: func() keyStatus { + ks := NewKeyStatus() + ks.Set("prof_123", STATUS_INPROCESS) + return *ks + }(), + + args: args{ + key: "prof_123", + }, + want: STATUS_INPROCESS, + }, + { + name: "With Valid key but not present in keyMap", + KeyS: *NewKeyStatus(), + args: args{ + key: "getAdUnit_5890", + }, + want: STATUS_NOTPRESENT, + }, + { + name: "With Invalid key and state as INPROCESS", + KeyS: *NewKeyStatus(), + args: args{ + key: "", + }, + want: STATUS_INVALID_KEY, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + ks := NewKeyStatus() + ks.keyMap = tt.KeyS.keyMap + t.Parallel() + if got := ks.Get(tt.args.key); got != tt.want { + t.Errorf("keyStatus.Get() = %v, want %v", got, tt.want) + } + }) + } +}