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

Couple of changes to exercise 2 #12

Merged
merged 5 commits into from
Sep 7, 2020
Merged

Couple of changes to exercise 2 #12

merged 5 commits into from
Sep 7, 2020

Conversation

benprew
Copy link
Contributor

@benprew benprew commented Aug 14, 2020

Hey,

Thanks for putting these exercise together, they're fun!

I wanted to expand on the exercise a little bit by adding some more detail to the problem and also adding an artificial slowdown to the mock database call to better simulate a call to a database. It also highlights the effects of different solutions (ie locking the entire function vs locking just the map/list access)

Finally I was noticed in the comments that it mentioned that it was an LRU cache, but it's implemented as a FIFO cache, so I included some changes to implement an LRU cache.

Let me know if there's any changes you'd like me to make, I'm happy to make any fixes.

Thanks!

@loong
Copy link
Owner

loong commented Aug 21, 2020

Hey Ben,

Thank you so much for the PR! Looks great so far. Will give it a closer view over the weekend! 🙏

Greetings from Singapore,
Long

@benprew
Copy link
Contributor Author

benprew commented Aug 22, 2020 via email

Copy link
Owner

@loong loong left a comment

Choose a reason for hiding this comment

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

Hey @benprew!

Thank you so much for the PR! Especially catching my mistake with the LRU. I hope no one used my implementation as a template for their own LRU cache implementation 😅.

I ran golint and got some errors. Better to solve them or my friend @ironzeb will give us a bad GoReportCard!

~/g/s/g/l/g/2-race-in-cache ❯❯❯ golint .
main.go:22:6: exported type Page should have comment or be unexported
main.go:47:9: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)

So, I only have a these small nitpicks. Once those are resolved, we can merge!

Greetings from tropical Singapore!

cache := New(&loader)

for i := 0; i < 100; i++ {
cache.Get("Test " + strconv.Itoa(i))
Copy link
Owner

Choose a reason for hiding this comment

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

Suggested change
cache.Get("Test " + strconv.Itoa(i))
cache.Get("Test" + strconv.Itoa(i))

I'm really nitpicking here, sorry 🙇 ! So, in the mock server, there isn't a space after Test:
https://github.com/loong/go-concurrency-exercises/blob/master/2-race-in-cache/mockserver.go#L29

It's all correct though 👍

@@ -20,3 +23,24 @@ func TestMain(t *testing.T) {
t.Errorf("Incorrect pages size %v", pagesLen)
}
}

func TestLRU(t *testing.T) {
Copy link
Owner

Choose a reason for hiding this comment

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

Test case! 🤩

@@ -19,9 +19,14 @@ type KeyStoreCacheLoader interface {
Load(string) string
}

type Page struct {
Copy link
Owner

Choose a reason for hiding this comment

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

Page is an exported value but has no comment!

From linter:
main.go:22:6: exported type Page should have comment or be unexported

Comment on lines 44 to 60
if e, ok := k.cache[key]; ok {
k.pages.MoveToFront(e)
return e.Value.(Page).Value
} else {
// Miss - load from database and save it in cache
page := Page{key, k.load(key)}
// if cache is full remove the least used item
if len(k.cache) > CacheSize {
delete(k.cache, k.pages.Back().Value.(string))
k.pages.Remove(k.pages.Back())
if len(k.cache) >= CacheSize {
end := k.pages.Back()
// remove from map
delete(k.cache, end.Value.(Page).Key)
// remove from list
k.pages.Remove(end)
}
k.pages.PushFront(page)
k.cache[key] = k.pages.Front()
return page.Value
Copy link
Owner

Choose a reason for hiding this comment

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

The if block ends with a return, so else block is not needed.

From linter:
main.go:47:9: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)

@benprew
Copy link
Contributor Author

benprew commented Aug 28, 2020 via email

@benprew
Copy link
Contributor Author

benprew commented Aug 29, 2020

Hey @loong thanks for the feedback, I think my changes address your feedback and the golint warnings. Let me know if I missed anything.

How's the weather in Singapore? I'm in Oregon, USA, where it's currently 70F (21C) and sunny, pretty perfect out right now.

@loong
Copy link
Owner

loong commented Aug 30, 2020

Well, it's an eternal summer here with at least 30°C (86°F) during the day. I grew up in Germany, so this is hot for me (especially with the humidity!). 😅

Went for a hike today!

photo_2020-08-30 20 57 00

EDIT: The picture above is totally necessary for this PR

Copy link
Owner

@loong loong left a comment

Choose a reason for hiding this comment

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

LGTM! Feel free to merge 🎉

Thank you so much for your contribution! Also, feel free to add your own exercise!

@@ -19,7 +19,7 @@ type KeyStoreCacheLoader interface {
Load(string) string
}

type Page struct {
type page struct {
Copy link
Owner

Choose a reason for hiding this comment

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

Haha, well that's also a way to pass the linter 😂

@benprew
Copy link
Contributor Author

benprew commented Sep 6, 2020

Thanks @loong, I'll send another PR if I think of some exercises 👍 . Also, I don't think I can merge this PR unless you grant me write access to your repo.

PS. that's a great picture, it's so beautiful and serene, more PRs could use pictures like that :)

@loong loong merged commit a36886f into loong:master Sep 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants