项目作者: golang-common-packages

项目描述 :
Linear data structure
高级语言: Go
项目地址: git://github.com/golang-common-packages/linear.git
创建时间: 2020-02-12T14:35:10Z
项目社区:https://github.com/golang-common-packages/linear

开源协议:MIT License

下载


Linear

godoc
Go Report Card

Linear

A Go package providing linear data structures and algorithms implementations.

Features

  • Implementations of common linear data structures (queue, stack, key-value store)
  • Configurable memory size limit with automatic eviction of oldest items when full
  • Thread-safe with fine-grained locking for concurrent access
  • Optimized for performance with minimal memory overhead
  • Well-tested with comprehensive test coverage
  • Support for various data types through Go’s interface{}
  • Efficient handling of duplicate keys

Requirements

  • Go 1.24 or higher

Installation

  1. go get github.com/golang-common-packages/linear

Usage

Import the package in your Go code:

  1. import "github.com/golang-common-packages/linear"

Basic example

  1. // Create a new Linear instance with 1024 bytes max size, no auto-eviction
  2. client := linear.New(1024, false)
  3. // Add a key-value pair
  4. client.Push("key1", "value1")
  5. // Remove and get the most recently added item (stack behavior)
  6. val, err := client.Pop()
  7. if err != nil {
  8. log.Fatalf("Error: %v", err)
  9. }
  10. fmt.Println(val) // Outputs: value1

Size limit with auto-eviction

  1. // Create a new Linear instance with 100 bytes max, enable auto-eviction
  2. client := linear.New(100, true)
  3. // Add multiple items that exceed the size limit
  4. for i := 0; i < 10; i++ {
  5. err := client.Push(fmt.Sprint(i), strings.Repeat("x", 20))
  6. if err != nil {
  7. log.Printf("Error pushing item %d: %v", i, err)
  8. }
  9. }
  10. // The oldest items will be removed automatically to respect size limit
  11. fmt.Println("Current items count:", client.GetNumberOfKeys())
  12. fmt.Println("Current size:", client.GetLinearCurrentSize())

Key-value operations

  1. client := linear.New(1024, false)
  2. // Add a key-value pair
  3. err := client.Push("user1", map[string]string{"name": "John", "role": "Admin"})
  4. if err != nil {
  5. log.Fatalf("Error: %v", err)
  6. }
  7. // Read a value without removing it
  8. user, err := client.Read("user1")
  9. if err != nil {
  10. log.Fatalf("Error: %v", err)
  11. }
  12. fmt.Println(user) // Outputs the user map
  13. // Update a value
  14. err = client.Update("user1", map[string]string{"name": "John", "role": "User"})
  15. if err != nil {
  16. log.Fatalf("Error: %v", err)
  17. }
  18. // Check if a key exists
  19. size, exists := client.IsExists("user1")
  20. if exists {
  21. fmt.Printf("Key exists with size: %d bytes\n", size)
  22. }
  23. // Get and remove a specific key
  24. user, err = client.Get("user1")
  25. if err != nil {
  26. log.Fatalf("Error: %v", err)
  27. }

Thread-safe concurrent access

  1. var wg sync.WaitGroup
  2. client := linear.New(1000, true)
  3. // Concurrent pushing of items
  4. for i := 0; i < 10; i++ {
  5. wg.Add(1)
  6. go func(i int) {
  7. defer wg.Done()
  8. err := client.Push(fmt.Sprint(i), "value")
  9. if err != nil {
  10. log.Printf("Error in goroutine %d: %v", i, err)
  11. }
  12. }(i)
  13. }
  14. wg.Wait()
  15. // Iterate over all items
  16. client.Range(func(key, value interface{}) bool {
  17. fmt.Printf("Key: %v, Value: %v\n", key, value)
  18. return true // continue iteration
  19. })

API Reference

Core Functions

  • New(maxSize int64, sizeChecker bool) *Linear - Create a new Linear instance
    • maxSize: Maximum memory size in bytes
    • sizeChecker: Enable auto-eviction when size limit is reached

Data Operations

  • Push(key string, value interface{}) error - Add or update a key-value pair
  • Pop() (interface{}, error) - Remove and return the most recently added item (stack behavior)
  • Take() (interface{}, error) - Remove and return the oldest item (queue behavior)
  • Get(key string) (interface{}, error) - Remove and return a specific item by key
  • Read(key string) (interface{}, error) - Read a value without removing it
  • Update(key string, value interface{}) error - Update an existing key’s value
  • Range(fn func(key, value interface{}) bool) - Iterate over all items

Utility Functions

  • IsExists(key string) (int64, bool) - Check if a key exists and get its size
  • IsEmpty() bool - Check if the Linear instance is empty
  • GetNumberOfKeys() int - Get the number of keys
  • GetLinearSizes() int64 - Get the maximum size limit
  • SetLinearSizes(linearSizes int64) error - Update the maximum size limit
  • GetLinearCurrentSize() int64 - Get the current used size

Size Calculation

The Linear package calculates the size of items as follows:

  • For strings: length of the string
  • For slices/arrays: length × element size
  • For maps/structs: fixed size of 64 bytes
  • For other types: size of the type as determined by reflection

This size calculation is used to enforce the memory size limit when sizeChecker is enabled.

Documentation

Full API documentation is available on pkg.go.dev.

Examples

See full_example.go for a complete usage example.

Testing

Unit Tests

  1. go test -v

Benchmarks

  1. go test -bench=. -benchmem -benchtime=30s

Benchmark results will vary depending on your hardware, but the package is optimized for both read and write operations.

Integration

For information on how to integrate this package with other storage solutions, see the storage package documentation.

Contributing

Pull requests are welcome. Please ensure:

  1. Tests pass with go test -v
  2. Code follows the project style
  3. Documentation is updated for any public API changes
  4. Benchmarks are included for performance-critical code

License

MIT