Skip to content

Commit

Permalink
Readme and examples
Browse files Browse the repository at this point in the history
  • Loading branch information
parMaster committed Jul 10, 2023
1 parent c593a5c commit 2f1f4c4
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 0 deletions.
137 changes: 137 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# mcache

`mcache` is a simple and thread-safe in-memory cache library for Go.

## Features

- Thread-safe cache operations
- Set key-value pairs with optional expiration time
- Get values by key
- Check if a key exists
- Delete key-value pairs
- Clear the entire cache
- Cleanup expired key-value pairs

## Installation

Use `go get` to install the package:

```shell
go get github.com/parMaster/mcache
```

## Usage

Import the `mcache` package in your Go code:

```go
import "github.com/parMaster/mcache"
```

Create a new cache instance using the `NewCache` constructor:

```go
cache := mcache.NewCache()
```

### Set

Set a key-value pair in the cache. The key must be a string, and the value can be any type that implements the `interface{}` interface, ttl is int64 value in seconds:

```go
err := cache.Set("key", "value", 0)
if err != nil {
// handle error
}
```

If the key already exists and is not expired, an error `mcache.ErrKeyExists` will be returned. If the key exists but is expired, the value will be updated.

You can also set a key-value pair with an expiration time (in seconds):

```go
err := cache.Set("key", "value", 60)
if err != nil {
// handle error
}
```

The value will automatically expire after the specified duration.

_Note that int64 is used instead of time.Duration for the expiration time. This choise is deliberate to simplify the API. It can be changed in the future, I can break the API but only in the next major version._

### Get

Retrieve a value from the cache by key:

```go
value, err := cache.Get("key")
if err != nil {
// handle error
}
```

If the key does not exist, an error `mcache.ErrKeyNotFound` will be returned. If the key exists but is expired, an error `mcache.ErrExpired` will be returned, and the key-value pair will be deleted.

Either error or value could be checked to determine if the key exists.

### Has

Check if a key exists in the cache:

```go
exists, err := cache.Has("key")
if err != nil {
// handle error
}

if exists {
// key exists
} else {
// key does not exist
}
```

If the key exists but is expired, an error `mcache.ErrExpired` will be returned, and the key-value pair will be deleted.

### Delete

Delete a key-value pair from the cache:

```go
err := cache.Del("key")
if err != nil {
// handle error
}
```

### Clear

Clear the entire cache:

```go
err := cache.Clear()
if err != nil {
// handle error
}
```

### Cleanup

Cleanup expired key-value pairs in the cache. You can call this method periodically to remove expired key-value pairs from the cache:

```go
cache.Cleanup()
```

## Examples

See the [examples](https://github.com/parMaster/mcache/examples) directory for more examples.

## Contributing

Contributions are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request.

## License

This project is licensed under the [GNU GPLv3](https://choosealicense.com/licenses/gpl-3.0/) license.
44 changes: 44 additions & 0 deletions examples/example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package main

import (
"fmt"
"time"

"github.com/parMaster/mcache"
)

func demo() {

fmt.Println("\r\n Demo 1:")
fmt.Println("------------------------------------------------------------")

cache := mcache.NewCache()

cache.Set("save indefinitely", "value without expiration", 0) // set value without expiration
cache.Set("save for 1 second", "value will expire in 1 second", 1) // set value with expiration in 1 second

exists, err := cache.Has("no such key")
// either exists or error can be checked
if err != nil {
// possible errors:
// mcache.ErrKeyNotFound
// mcache.ErrExpired
fmt.Println(err)
}
if !exists {
fmt.Println("key doen't exist or expired")
}

v, _ := cache.Get("save indefinitely")
fmt.Println(v)

time.Sleep(1 * time.Second)
v, _ = cache.Get("save for 1 second")
fmt.Println(v) // <nil> because key expired

}

func main() {
demo()
demo_hit_or_miss()
}
32 changes: 32 additions & 0 deletions examples/hit_or_miss.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"fmt"
"time"

"github.com/parMaster/mcache"
)

func expensive_func() interface{} {
time.Sleep(1 * time.Second)
return "expensive result"
}

func demo_hit_or_miss() {
fmt.Println("\r\n Hit or Miss:")
fmt.Println("------------------------------------------------------------")

cache := mcache.NewCache()
// expensive_func will be called only once
// because result will be saved in cache
for i := 0; i < 10; i++ {
v, err := cache.Get("expensive value")
if err != nil {
fmt.Println("cache miss, calling expensive_func")
v = expensive_func()
cache.Set("expensive value", v, 0)
continue
}
fmt.Println("cache hit - " + v.(string))
}
}

0 comments on commit 2f1f4c4

Please sign in to comment.