Skip to content

Commit

Permalink
use maps instead of tst (#42)
Browse files Browse the repository at this point in the history
* use maps instead of tst

* add dependabot

* update readme
  • Loading branch information
abahmed committed Jun 18, 2020
1 parent ed6fbee commit 09ddb25
Show file tree
Hide file tree
Showing 17 changed files with 334 additions and 431 deletions.
4 changes: 2 additions & 2 deletions .github/auto_assign.yml
Expand Up @@ -5,10 +5,10 @@ addReviewers: true
addAssignees: true

# A list of reviewers to be added to pull requests (GitHub user name)
reviewers:
reviewers:
- abahmed

# A list of keywords to be skipped the process that add reviewers if pull requests include it
# A list of keywords to be skipped the process that add reviewers if pull requests include it
skipKeywords:
- wip

Expand Down
6 changes: 6 additions & 0 deletions .github/dependabot.yml
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"
2 changes: 1 addition & 1 deletion .github/workflows/security.yml
Expand Up @@ -16,7 +16,7 @@ jobs:
env:
GO111MODULE: on
steps:
- name: Checkout Source
- name: Checkout Source
uses: actions/checkout@v2
- name: Run Gosec Security Scanner
uses: securego/gosec@master
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test_and_build.yml
Expand Up @@ -40,13 +40,13 @@ jobs:

- name: Install dependencies
run: go get -v golang.org/x/lint/golint

- name: Build
run: go build

- name: Lint
run: golint -set_exit_status ./...

- name: Test
run: go test -race --coverprofile=coverage.txt --covermode=atomic ./...

Expand Down
33 changes: 18 additions & 15 deletions README.md
Expand Up @@ -81,17 +81,17 @@ func main() {

// Handler with parameter
gb.Get("/users/:user", func(ctx *gearbox.Context) {
fmt.Printf("%s\n", ctx.Params.GetString("user"))
fmt.Printf("%s\n", ctx.Params["user"])
})

// Handler with optional parameter
gb.Get("/search/:pattern?", func(ctx *gearbox.Context) {
fmt.Printf("%s\n", ctx.Params.GetString("pattern"))
fmt.Printf("%s\n", ctx.Params["pattern"])
})

// Handler with regex parameter
gb.Get("/book/:name:([a-z]+[0-3])", func(ctx *gearbox.Context) {
fmt.Printf("%s\n", ctx.Params.GetString("name"))
fmt.Printf("%s\n", ctx.Params["name"])
})

// Start service
Expand Down Expand Up @@ -132,18 +132,21 @@ func main() {
ctx.RequestCtx.Response.SetBodyString("Hello World!")
})

// Register the routes to be used when grouping routes
routes := []*gearbox.Route{gb.Get("/id", func(ctx *gearbox.Context) {
ctx.RequestCtx.Response.SetBodyString("User X")
}), gb.Delete("/id", func(ctx *gearbox.Context) {
ctx.RequestCtx.Response.SetBodyString("Deleted")
})}

// Group account routes
accountRoutes := gb.Group("/account", routes)

// Group account routes to be under api
gb.Group("/api", accountRoutes)
// Register the routes to be used when grouping routes
routes := []*gearbox.Route {
gb.Get("/id", func(ctx *gearbox.Context) {
ctx.RequestCtx.Response.SetBodyString("User X")
}),
gb.Delete("/id", func(ctx *gearbox.Context) {
ctx.RequestCtx.Response.SetBodyString("Deleted")
})
}

// Group account routes
accountRoutes := gb.Group("/account", routes)

// Group account routes to be under api
gb.Group("/api", accountRoutes)

// Define a route with unAuthorizedMiddleware as the middleware
// you can define as many middlewares as you want and have the handler as the last argument
Expand Down
39 changes: 19 additions & 20 deletions cache.go
Expand Up @@ -7,28 +7,28 @@ import (

// Implementation of LRU caching using doubly linked list and tst

// cache returns LRU cache
type cache interface {
Set(key []byte, value interface{})
Get(key []byte) interface{}
// Cache returns LRU cache
type Cache interface {
Set(key string, value interface{})
Get(key string) interface{}
}

// lruCache holds info used for caching internally
type lruCache struct {
capacity int
list *list.List
store tst
store map[string]interface{}
mutex sync.RWMutex
}

// pair contains key and value of element
type pair struct {
key []byte
key string
value interface{}
}

// newCache returns LRU cache
func newCache(capacity int) cache {
// NewCache returns LRU cache
func NewCache(capacity int) Cache {
// minimum is 1
if capacity <= 0 {
capacity = 1
Expand All @@ -37,17 +37,17 @@ func newCache(capacity int) cache {
return &lruCache{
capacity: capacity,
list: new(list.List),
store: newTST(),
store: make(map[string]interface{}),
}
}

// Get returns value of provided key if it's existing
func (c *lruCache) Get(key []byte) interface{} {
func (c *lruCache) Get(key string) interface{} {
c.mutex.RLock()
defer c.mutex.RUnlock()

// check if list node exists
if node, ok := c.store.Get(key).(*list.Element); ok {
if node, ok := c.store[key].(*list.Element); ok {
c.list.MoveToFront(node)

return node.Value.(*pair).value
Expand All @@ -56,31 +56,30 @@ func (c *lruCache) Get(key []byte) interface{} {
}

// Set adds a value to provided key in cache
func (c *lruCache) Set(key []byte, value interface{}) {
func (c *lruCache) Set(key string, value interface{}) {
c.mutex.Lock()
defer c.mutex.Unlock()

// update the value if key is existing
if node, ok := c.store.Get(key).(*list.Element); ok {
if node, ok := c.store[key].(*list.Element); ok {
c.list.MoveToFront(node)
node.Value.(*pair).value = value

node.Value.(*pair).value = value
return
}

// remove last node if cache is full
if c.list.Len() == c.capacity {
lastKey := c.list.Back().Value.(*pair).key
lastNode := c.list.Back()

// delete key's value
c.store.Set(lastKey, nil)
delete(c.store, lastNode.Value.(*pair).key)

c.list.Remove(c.list.Back())
c.list.Remove(lastNode)
}

newValue := &pair{
c.store[key] = c.list.PushFront(&pair{
key: key,
value: value,
}
c.store.Set(key, c.list.PushFront(newValue))
})
}
43 changes: 23 additions & 20 deletions cache_test.go
@@ -1,32 +1,35 @@
package gearbox

import "fmt"
import (
"fmt"
)

// ExampleCache tests Cache set and get methods
func ExampleCache() {
cache := newCache(3)
cache.Set([]byte("user1"), 1)
fmt.Println(cache.Get([]byte("user1")).(int))
// ExampleNewCache tests Cache set and get methods
func ExampleNewCache() {
cache := NewCache(3)
cache.Set("user1", 1)
fmt.Println(cache.Get("user1").(int))

cache.Set([]byte("user2"), 2)
fmt.Println(cache.Get([]byte("user2")).(int))
cache.Set("user2", 2)
fmt.Println(cache.Get("user2").(int))

cache.Set([]byte("user3"), 3)
fmt.Println(cache.Get([]byte("user3")).(int))
cache.Set("user3", 3)
fmt.Println(cache.Get("user3").(int))

cache.Set([]byte("user4"), 4)
fmt.Println(cache.Get([]byte("user1")))
fmt.Println(cache.Get([]byte("user2")).(int))
cache.Set("user4", 4)
fmt.Println(cache.Get("user1"))
fmt.Println(cache.Get("user2").(int))

cache.Set([]byte("user5"), 5)
fmt.Println(cache.Get([]byte("user3")))
cache.Set("user5", 5)
fmt.Println(cache.Get("user3"))

cache.Set([]byte("user5"), 6)
fmt.Println(cache.Get([]byte("user5")).(int))
cache.Set("user5", 6)
fmt.Println(cache.Get("user5").(int))

cache2 := NewCache(0)
cache2.Set("user1", 1)
fmt.Println(cache2.Get("user1").(int))

cache2 := newCache(0)
cache2.Set([]byte("user1"), 1)
fmt.Println(cache2.Get([]byte("user1")).(int))
// Output:
// 1
// 2
Expand Down
2 changes: 1 addition & 1 deletion context.go
Expand Up @@ -13,7 +13,7 @@ type handlersChain []handlerFunc
// Context defines the current context of request and handlers/middlewares to execute
type Context struct {
RequestCtx *fasthttp.RequestCtx
Params tst
Params map[string]string
handlers handlersChain
index int
}
Expand Down

0 comments on commit 09ddb25

Please sign in to comment.