{"id":46088117,"url":"https://github.com/llxisdsh/pb","last_synced_at":"2026-03-01T17:09:24.273Z","repository":{"id":281607643,"uuid":"945748188","full_name":"llxisdsh/pb","owner":"llxisdsh","description":"MapOf is a high-performance concurrent map implementation that offers significant, performance improvements over sync.Map in many common scenarios.","archived":false,"fork":false,"pushed_at":"2026-02-11T05:25:48.000Z","size":1723,"stargazers_count":21,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-11T11:32:47.435Z","etag":null,"topics":["clht","concurrent","fastest","go","hashmap","map","swisstable"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/llxisdsh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-03-10T04:07:01.000Z","updated_at":"2026-02-11T05:12:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"ea293698-8cbc-4aee-a888-dd48f86c49b2","html_url":"https://github.com/llxisdsh/pb","commit_stats":null,"previous_names":["llxisdsh/pb"],"tags_count":94,"template":false,"template_full_name":null,"purl":"pkg:github/llxisdsh/pb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llxisdsh%2Fpb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llxisdsh%2Fpb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llxisdsh%2Fpb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llxisdsh%2Fpb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/llxisdsh","download_url":"https://codeload.github.com/llxisdsh/pb/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/llxisdsh%2Fpb/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29976272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T16:35:47.903Z","status":"ssl_error","status_checked_at":"2026-03-01T16:35:44.899Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clht","concurrent","fastest","go","hashmap","map","swisstable"],"created_at":"2026-03-01T17:09:23.717Z","updated_at":"2026-03-01T17:09:24.267Z","avatar_url":"https://github.com/llxisdsh.png","language":"Go","readme":"\u003c!--\n[![Go Reference](https://pkg.go.dev/badge/github.com/llxisdsh/pb.svg)](https://pkg.go.dev/github.com/llxisdsh/pb)[![Go Report Card](https://goreportcard.com/badge/github.com/llxisdsh/pb)](https://goreportcard.com/report/github.com/llxisdsh/pb)[![Codecov](https://codecov.io/gh/llxisdsh/pb/branch/main/graph/badge.svg)](https://codecov.io/gh/llxisdsh/pb)[![GitHub Actions](https://github.com/llxisdsh/pb/actions/workflows/go.yml/badge.svg?branch=main)](https://github.com/llxisdsh/pb/actions)\n--\u003e\n\n\u003e This repository is stable and focuses on bug fixes.\nPrefer a simpler API with more concurrency primitives? Try\n[Concurrent Core](https://llxisdsh.github.io/cc/) — a lightweight, high‑performance Go toolkit for\nlatency‑critical paths.\n\n# MapOf\n\nMapOf is a high-performance concurrent map optimized for read-dominant and mixed read/write workloads, outperforming sync.Map in many common scenarios. Its core design combines lock-free reads with bucket-level fine-grained synchronization on writes, together with cache-line–aware layout, parallel resizing, and pluggable hashing/equality. This yields high throughput with markedly improved tail-latency stability.\n\nDesign highlights\n- Lock-free read path; the write path employs bucket-level fine-grained synchronization and backoff to ensure forward progress under high contention.\n- Cache-line alignment and suppression of false sharing to reduce cross-line accesses and hot-spot interference.\n- CPU cache-line size adaptation (optionally specified at build time), with counter padding to reduce contention overhead.\n- Supports preallocation (WithPresize) and automatic shrinking (WithShrinkEnabled) to enhance memory elasticity and cold-start performance.\n- Zero-value usability and lazy initialization to reduce integration complexity.\n- Full sync.Map API compatibility, plus extensions: LoadOrStoreFn, ProcessEntry, Size, IsZero, Clone, and batch operations.\n- Parallel resizing to lower resize tail latency and improve scalability.\n- Pluggable hashing and equality: WithKeyHasher / IHashCode / WithValueEqual / IEqual, enabling domain-specific tuning for keys/values.\n- Defaults to Go’s built-in hashing; when hash computation is expensive, embedded hash caching can be enabled via mapof_opt_embeddedhash.\n\nApplicability (overview)\n- Suitable for read-intensive caches, online low-latency key–value access, and shared-state management requiring atomic conditional updates; under resource constraints, shrinking and custom hashing can further improve space efficiency and stability.\n\nValidated across multiple platforms with adaptive optimizations for strong memory models (e.g., x86 TSO). See the benchmarks below for details.\n\n## 📊 Comprehensive Benchmarks\n\nBenchmark results consistently show MapOf outperforms other implementations with the fastest operations across Store, \nLoadOrStore, Load, and Mixed workloads.\n\n```\ngoos: windows\ngoarch: amd64\npkg: github.com/llxisdsh/pb\ncpu: AMD Ryzen Threadripper 3970X 32-Core Processor \n```\n\n\n\u003cdetails\u003e\n\u003csummary\u003e Benchmark Test (09/01/2025) \u003c/summary\u003e\n\n```go\nconst countStore = 1_000_000\nconst countLoadOrStore = countStore\nconst countLoad = min(1_000_000, countStore)\n\nfunc mixRand(i int) int {\n    return i \u0026 (8 - 1)\n}\n\nfunc BenchmarkStore_original_syncMap(b *testing.B) {\n    b.ReportAllocs()\n    var m sync.Map\n    runtime.GC()\n    b.ResetTimer()\n    b.RunParallel(func(pb *testing.PB) {\n        i := 0\n        for pb.Next() {\n            m.Store(i, i)\n            i++\n            if i \u003e= countStore {\n                i = 0\n            }\n        }\n    })\n}\n\nfunc BenchmarkLoadOrStore_original_syncMap(b *testing.B) {\n    b.ReportAllocs()\n    var m sync.Map\n    runtime.GC()\n    b.ResetTimer()\n    b.RunParallel(func(pb *testing.PB) {\n        i := 0\n        for pb.Next() {\n            _, _ = m.LoadOrStore(i, i)\n            i++\n            if i \u003e= countLoadOrStore {\n                i = 0\n            }\n        }\n    })\n}\n\nfunc BenchmarkLoad_original_syncMap(b *testing.B) {\n\n    b.ReportAllocs()\n    var m sync.Map\n    for i := 0; i \u003c countLoad; i++ {\n        m.Store(i, i)\n    }\n    runtime.GC()\n    b.ResetTimer()\n    b.RunParallel(func(pb *testing.PB) {\n        i := 0\n        for pb.Next() {\n            _, _ = m.Load(i)\n            i++\n            if i \u003e= countLoad {\n                i = 0\n            }\n        }\n    })\n}\n\nfunc BenchmarkMixed_original_syncMap(b *testing.B) {\n    b.ReportAllocs()\n    var m sync.Map\n    for i := 0; i \u003c countLoad; i++ {\n        m.Store(i, i)\n    }\n    runtime.GC()\n\n    b.ResetTimer()\n    b.RunParallel(func(pb *testing.PB) {\n        i := 0\n        for pb.Next() {\n            r := mixRand(i)\n            if r == 0 {\n                m.Store(i, i)\n            } else if r == 1 {\n                m.Delete(i)\n            } else if r == 2 {\n                _, _ = m.LoadOrStore(i, i)\n            } else {\n                _, _ = m.Load(i)\n            }\n            i++\n            if i \u003e= countLoad\u003c\u003c1 {\n                i = 0\n            }\n        }\n    })\n}\n\n```\n\u003c/details\u003e\n\n| Implementation               | Operation   |       Ops/sec |   ns/op | B/op | Allocs/op |\n|------------------------------|-------------|--------------:|--------:|-----:|----------:|\n| original_syncMap             | Store       |    43,408,107 |   26.24 |   64 |         3 |\n|                              | LoadOrStore |    64,053,295 |   19.23 |   17 |         2 |\n|                              | Load        |   387,208,314 |    3.80 |    0 |         0 |\n|                              | Mixed       |   153,055,444 |    8.24 |   10 |         0 |\n| pb_MapOf 🏆                  | Store       | 1,000,000,000 |    0.58 |    0 |         0 |\n|                              | LoadOrStore | 1,000,000,000 |    0.47 |    0 |         0 |\n|                              | Load        | 1,000,000,000 |    0.18 |    0 |         0 |\n|                              | Mixed       | 1,000,000,000 |    0.42 |    0 |         0 |\n| pb_FlatMapOf 🥈              | Store       | 1,000,000,000 |    0.93 |    0 |         0 |\n|                              | LoadOrStore | 1,000,000,000 |    0.61 |    0 |         0 |\n|                              | Load        | 1,000,000,000 |    0.22 |    0 |         0 |\n|                              | Mixed       | 1,000,000,000 |    0.65 |    0 |         0 |\n| xsync_MapOf                  | Store       |   136,297,424 |    8.47 |   16 |         1 |\n|                              | LoadOrStore |   27,398,7921 |    4.00 |    0 |         0 |\n|                              | Load        |   74,548,1913 |    1.59 |    0 |         0 |\n|                              | Mixed       |   47,340,9570 |    2.27 |    2 |         0 |\n| pb_HashTrieMap               | Store       |    62,662,484 |   18.30 |   48 |         1 |\n|                              | LoadOrStore |    86,982,994 |   11.95 |    1 |         0 |\n|                              | Load        |   463,348,550 |    3.58 |    0 |         0 |\n|                              | Mixed       |   198,404,397 |    6.16 |    6 |         0 |\n| alphadose_haxmap             | Store       |    80,418,174 |   14.01 |    9 |         1 |\n|                              | LoadOrStore |    75,698,793 |   14.39 |    9 |         1 |\n|                              | Load        |   767,338,982 |    1.92 |    0 |         0 |\n|                              | Mixed       |   186,024,159 |    5.52 |    2 |         0 |\n| zhangyunhao116_skipmap       | Store       |    29,587,840 |   39.17 |    9 |         1 |\n|                              | LoadOrStore |    37,524,507 |   30.38 |    1 |         0 |\n|                              | Load        |   527,466,034 |    2.27 |    0 |         0 |\n|                              | Mixed       |   183,319,764 |    6.22 |    1 |         0 |\n| riraccuia_ash                | Store       |    51,692,203 |   21.81 |   62 |         4 |\n|                              | LoadOrStore |    28,938,676 |   41.67 |   94 |         3 |\n|                              | Load        |   269,917,735 |    4.64 |    7 |         0 |\n|                              | Mixed       |   124,839,320 |    9.94 |   18 |         1 |\n| fufuok_cmap                  | Store       |    29,590,686 |   38.21 |    1 |         0 |\n|                              | LoadOrStore |    43,682,427 |   27.92 |    0 |         0 |\n|                              | Load        |   151,875,836 |    7.74 |    0 |         0 |\n|                              | Mixed       |    25,265,125 |   46.51 |    0 |         0 |\n| mhmtszr_concurrent_swiss_map | Store       |    29,849,112 |   40.21 |    1 |         0 |\n|                              | LoadOrStore |    27,447,705 |   45.02 |    0 |         0 |\n|                              | Load        |   163,669,803 |    7.66 |    0 |         0 |\n|                              | Mixed       |    30,439,160 |   36.53 |    0 |         0 |\n| orcaman_concurrent_map       | Store       |    34,420,544 |   33.46 |    1 |         0 |\n|                              | LoadOrStore |    50,175,614 |   25.41 |    1 |         0 |\n|                              | Load        |   145,646,887 |    8.70 |    0 |         0 |\n|                              | Mixed       |    48,974,994 |   26.18 |    0 |         0 |\n| RWLockShardedMap_256         | Store       |    69,052,428 |   15.79 |    1 |         0 |\n|                              | LoadOrStore |   119,077,255 |    9.45 |    0 |         0 |\n|                              | Load        |   287,863,598 |    4.17 |    0 |         0 |\n|                              | Mixed       |   172,448,331 |    6.98 |    0 |         0 |\n| RWLockMap                    | Store       |     4,238,468 |  269.00 |    1 |         0 |\n|                              | LoadOrStore |     9,066,169 |  163.10 |    1 |         0 |\n|                              | Load        |    33,225,810 |   36.11 |    0 |         0 |\n|                              | Mixed       |     9,591,573 |  127.70 |    0 |         0 |\n| snawoot_lfmap                | Store       |       364,705 | 3153.00 | 7754 |        48 |\n|                              | LoadOrStore |     8,887,498 |  205.60 |  518 |         2 |\n|                              | Load        |   281,609,623 |    4.22 |    0 |         0 |\n|                              | Mixed       |     1,899,039 |  630.00 | 2453 |        10 |\n\n\n- RWLockShardedMap_256: A 256-shard concurrent map using Go's native map + RWMutex per shard (benchmark reference). \n  Sharding theoretically boosts performance/throughput for any map.\n\n\n\u003cdetails\u003e\n\u003csummary\u003e Store Throughput Test (09/23/2025) \u003c/summary\u003e\n\n```go\n\nconst total = 100_000_000\n\nfunc testInsert_pb_MapOf(t *testing.T, total int, numCPU int, preSize bool) {\n    time.Sleep(2 * time.Second)\n    runtime.GC()\n    \n    var m *MapOf[int, int]\n    if preSize {\n        m = NewMapOf[int, int](WithPresize(total))\n    } else {\n        m = NewMapOf[int, int]()\n    }\n\n    var wg sync.WaitGroup\n    wg.Add(numCPU)\n\n    start := time.Now()\n\n    batchSize := total / numCPU\n\n    for i := 0; i \u003c numCPU; i++ {\n        go func(start, end int) {\n            //defer wg.Done()\n\n            for j := start; j \u003c end; j++ {\n                m.Store(j, j)\n            }\n            wg.Done()\n        }(i*batchSize, min((i+1)*batchSize, total))\n    }\n\n    wg.Wait()\n\n    elapsed := time.Since(start)\n\n    size := m.Size()\n    if size != total {\n        t.Errorf(\"Expected size %d, got %d\", total, size)\n    }\n\n    t.Logf(\"Inserted %d items in %v\", total, elapsed)\n    t.Logf(\"Average: %.2f ns/op\", float64(elapsed.Nanoseconds())/float64(total))\n    t.Logf(\"Throughput: %.2f million ops/sec\", float64(total)/(elapsed.Seconds()*1000000))\n\n    // rand check\n    for i := 0; i \u003c 1000; i++ {\n        idx := i * (total / 1000)\n        if val, ok := m.Load(idx); !ok || val != idx {\n            t.Errorf(\"Expected value %d at key %d, got %d, exists: %v\", idx, idx, val, ok)\n        }\n    }\n}\n\nfunc TestInsert_pb_MapOf(t *testing.T) {\n    t.Run(\"1 no_pre_size\", func(t *testing.T) {\n        testInsert_pb_MapOf(t, total, 1, false)\n    })\n\n    t.Run(\"64 no_pre_size\", func(t *testing.T) {\n        testInsert_pb_MapOf(t, total, runtime.GOMAXPROCS(0), false)\n    })\n    t.Run(\"1 pre_size\", func(t *testing.T) {\n        testInsert_pb_MapOf(t, total, 1, true)\n    })\n\n    t.Run(\"64 pre_size\", func(t *testing.T) {\n        testInsert_pb_MapOf(t, total, runtime.GOMAXPROCS(0), true)\n    })\n}\n```\n\u003c/details\u003e\n\n| Implementation \u0026 Case       | Throughput\u003cbr\u003e(M ops/s) | Performance Scale        |\n|-----------------------------|------------------------:|--------------------------|\n| pb_FlatMapOf (64/pre)       |                  262.42 | ━━━━━━━━━━━━━━━━━━━━━━━━ |\n| pb_FlatMapOf (64)           |                  108.37 | ━━━━━━━━━━━━━━━          |\n| pb_FlatMapOf (1/pre)        |                   31.44 | ━━━━━━━━                 |\n| pb_FlatMapOf (1)            |                   22.93 | ━━━━━━                   |\n| pb_MapOf (64/pre)           |                  178.09 | ━━━━━━━━━━━━━━━━━        |\n| pb_MapOf (64)               |                   94.21 | ━━━━━━━━━━━              |\n| pb_MapOf (1/pre)            |                   26.83 | ━━━━━━━                  |\n| pb_MapOf (1)                |                   21.45 | ━━━━━                    |\n| xsync_MapV4 (64/pre)        |                   91.83 | ━━━━━━━━━━━              |\n| xsync_MapV4 (64)            |                   25.47 | ━━━━━━━                  |\n| xsync_MapV4 (1/pre)         |                    5.86 | ━━                       |\n| xsync_MapV4 (1)             |                    3.23 | ━━                       |\n| pb_HashTrieMap (64)         |                   25.54 | ━━━━━━━                  |\n| pb_HashTrieMap (1)          |                    1.73 | ━                        |\n| zhangyunhao116_skipmap (64) |                   25.37 | ━━━━━━━                  |\n| zhangyunhao116_skipmap (1)  |                    3.38 | ━━                       |\n| RWLockShardedMap_256 (64)   |                   21.92 | ━━━━━                    |\n| RWLockShardedMap_256 (1)    |                    3.47 | ━━                       |\n| original_syncMap (64)       |                   21.84 | ━━━━━                    |\n| original_syncMap (1)        |                    1.42 | ━                        |\n| alphadose_haxmap (64/pre)   |                    2.88 | ━                        |\n| alphadose_haxmap (64)       |                    0.57 |                          |\n| alphadose_haxmap (1/pre)    |                    1.00 | ━                        |\n| alphadose_haxmap (1)        |                    0.92 | ━                        |\n\n\n- (1): 1 goroutine without pre-allocation\n- (1/pre): 1 goroutine with pre-allocation\n- (64): 64 goroutines without pre-allocation\n- (64/pre): 64 goroutines with pre-allocation\n\n\u003cdetails\u003e\n\u003csummary\u003e Memory Usage Test (08/04/2025) \u003c/summary\u003e\n\n```go\nfunc Test_MemoryPeakReduction(t *testing.T) {\n    if testing.Short() {\n        t.Skip(\"Skipping memory test in short mode\")\n    }\n    \n    const numItems = 100000\n    \n    var m1, m2 runtime.MemStats\n    runtime.GC()\n    runtime.ReadMemStats(\u0026m1)\n    \n    m := NewMapOf[int, int]()\n    \n    for i := 0; i \u003c numItems; i++ {\n        m.Store(i, i)\n    }\n    runtime.GC()\n    runtime.ReadMemStats(\u0026m2)\n    \n    peak := m2.Alloc - m1.Alloc\n    t.Logf(\"pb_MapOf memory usage: %d bytes, items: %d\", peak, m.Size())\n}\n```\n\u003c/details\u003e\n\nBenchmark results indicate that MapOf matches the native Go map in memory efficiency, and even outperforms it in most scenarios.\n![Memory Usage Comparison (log scale)](./res/memory_usage_comparison_log_scale.png)\n![Memory Usage Comparison (Linear scale)](./res/memory_usage_comparison_linear_scale.png)\n\n## ⚡ Performance Tips\n\nTo achieve exceptional performance, MapOf employs multiple optimization strategies:\n\n### Optimization Strategies\n\n#### 1. Built-in Optimizations (Automatic)\n- **Integer Key Optimization**: Uses raw key values as hash for integer types, delivering 4-6x performance improvement\n- **String Key Optimization**: Automatically enabled for short string and []byte keys (≤12 bytes), achieving 2-3x performance improvement\n- **Memory Layout Optimization**: Cache-line aligned structures prevent false sharing\n\n**Note**: Default optimizations may increase hash collision rates in some scenarios. For domain-specific optimizations, see custom hash functions in the Usage section.\n\n#### 2. Configurable Optimizations\n- **Pre-sizing**: Use `WithPresize(n)` to avoid rehashing during initial population\n- **Shrink Control**: Use `WithShrinkEnabled()` to automatically reduce memory usage when map size decreases\n- **Custom Hash Functions**: Implement `IHashCode` interface or use `WithKeyHasher()` for specialized key types (see Usage section for examples)\n\n#### 3. Performance Guidelines\n- Custom hash functions provide significant gains for domain-specific key types\n- Interface implementations are automatically detected at initial time\n- `With*` functions take precedence over interface implementations\n- Well-designed custom hash functions typically outweigh collision risks\n- WithBuiltInHasher() uses Go's native map hashing, ideal for random keys with no sequential-key acceleration.\n\n## 🚀 Quick Start\n\n### Installation\n\n```bash\ngo get github.com/llxisdsh/pb@latest\n```\n\n\n### Prerequisites\n\nThe MapOf implementation uses `golang.org/x/sys` to determine the system's `CacheLineSize`.\nFor optimal performance, ensure your build environment has the latest version of this dependency:\n```\ngo get golang.org/x/sys@latest\n```\n\n### Usage\n\n#### 1. Basic Initialization\n\n```go\npackage main\n\nimport (\n    \"github.com/llxisdsh/pb\"\n)\n\nfunc main() {\n    // Zero-value initialization with lazy loading\n    var cache pb.MapOf[string, int]\n\n    // Optional initialization, Must be called once before use.\n    cache.InitWithOptions(pb.WithPresize(1000000))\n\n    // Direct initialization with options\n    cache2 := pb.NewMapOf[string, int](pb.WithPresize(1000000), pb.WithShrinkEnabled())\n}\n```\n\n#### 2. Basic Read/Write Operations\n\n```go\nimport (\n    \"fmt\"\n    \"github.com/llxisdsh/pb\"\n)\n\nfunc basicOperations() {\n    cache := pb.NewMapOf[string, int]()\n\n    // Store and load values\n    cache.Store(\"key1\", 100)\n    cache.Store(\"key2\", 200)\n\n    value, exists := cache.Load(\"key1\")\n    if exists {\n        fmt.Printf(\"key1: %d\\n\", value)\n    }\n\n    // Load or store atomically\n    actual, loaded := cache.LoadOrStore(\"key3\", 300)\n    if loaded {\n        fmt.Printf(\"key3 already exists: %d\\n\", actual)\n    } else {\n        fmt.Printf(\"key3 stored: %d\\n\", actual)\n    }\n\n    cache.Delete(\"key2\")\n}\n```\n\n#### 3. Atomic Operations\n\n```go\nimport (\n    \"fmt\"\n    \"github.com/llxisdsh/pb\"\n)\n\nfunc atomicOperations() {\n    cache := pb.NewMapOf[string, int]()\n    cache.Store(\"key1\", 100)\n\n    // Atomic swap\n    oldValue, swapped := cache.Swap(\"key1\", 150)\n    if swapped {\n        fmt.Printf(\"Swapped key1 from %d to 150\\n\", oldValue)\n    }\n\n    // Compare and swap\n    swapped = cache.CompareAndSwap(\"key1\", 150, 175)\n    if swapped {\n        fmt.Println(\"Successfully swapped key1 from 150 to 175\")\n    }\n\n    // Compare and delete\n    deleted := cache.CompareAndDelete(\"key1\", 175)\n    if deleted {\n        fmt.Println(\"Successfully deleted key1 with value 175\")\n    }\n\n    // Lazy value generation\n    result, loaded := cache.LoadOrStoreFn(\"computed:key\", func() int {\n        fmt.Println(\"Computing expensive value...\")\n        return 43\n    })\n    fmt.Printf(\"Result: %d, Loaded: %t\\n\", result, loaded)\n\n    // ProcessEntry: Atomic conditional processing with complex business logic\n    cache.ProcessEntry(\"user:789\", func(entry *pb.EntryOf[string, int]) (*pb.EntryOf[string, int], int, bool) {\n        if entry != nil {\n            // Update existing entry\n            newEntry := \u0026pb.EntryOf[string, int]{Value: entry.Value + 1}\n            return newEntry, entry.Value, true\n        }\n        // Create new entry\n        return \u0026pb.EntryOf[string, int]{Value: 1}, 0, false\n    })\n\n    // LoadAndDelete: Atomic read-and-delete operation\n    deletedValue, wasPresent := cache.LoadAndDelete(\"user:456\")\n    fmt.Printf(\"Deleted value: %d, Was present: %t\\n\", deletedValue, wasPresent)\n\n    // LoadAndUpdate: Atomic read-and-update operation\n    previousValue, wasUpdated := cache.LoadAndUpdate(\"counter\", 1)\n    fmt.Printf(\"Previous: %d, Updated: %t\\n\", previousValue, wasUpdated)\n}\n```\n\n#### 4. Custom Hash Functions and Equality\n\n```go\nimport (\n    \"slices\"\n    \"github.com/llxisdsh/pb\"\n)\n\nfunc customOptimizations() {\n    // Configuration Priority (highest to lowest):\n    //   - Explicit With* functions (WithKeyHasher, WithValueEqual)\n    //   - Interface implementations (IHashCode, IEqual)\n    //   - Default built-in implementations (defaultHasher) - fallback\n    \n    // Method 1: Using With* functions for runtime configuration\n\n    // Built-in hasher: better for long strings (lower collisions) but slower for short strings (2-3x)\n    stringCache := pb.NewMapOf[string, int](pb.WithBuiltInHasher[string]())\n\n    // Custom hash function for pointer keys\n    type UserID struct {\n        UserID   int64\n        TenantID int64\n    }\n    userCache := pb.NewMapOf[UserID, string](pb.WithKeyHasher(func(key UserID, seed uintptr) uintptr {\n        return uintptr(key.UserID) ^ seed\n    }))\n\n    // Method 2: Interface-based (runtime init check)\n    type CustomKey struct {\n        ID   int64\n        Name string\n    }\n\n    // Implement IHashCode for custom hashing\n    func (c *CustomKey) HashCode(uintptr) uintptr {\n        return uintptr(c.ID)\n    }\n\n    // Custom value type with IEqual for non-comparable types\n    type UserProfile struct {\n        Name string\n        Tags []string // slice makes this non-comparable\n    }\n\n    func (u *UserProfile) Equal(other UserProfile) bool {\n        return u.Name == other.Name \u0026\u0026 slices.Equal(u.Tags, other.Tags)\n    }\n\n    // Automatically detects and uses interfaces\n    var interfaceCache MapOf[CustomKey, UserProfile]\n    // Or\n    interfaceCache2 := pb.NewMapOf[CustomKey, UserProfile]()\n}\n```\n\n#### 5. Iteration Operations\n\n```go\nimport (\n    \"fmt\"\n    \"github.com/llxisdsh/pb\"\n)\n\nfunc iterationOperations() {\n    cache := pb.NewMapOf[string, int]()\n    cache.Store(\"key1\", 100)\n    cache.Store(\"key2\", 200)\n\n    // Range over all key-value pairs\n    cache.Range(func(key string, value int) bool {\n        fmt.Printf(\"Key: %s, Value: %d\\n\", key, value)\n        return true // continue iteration\n    })\n\n    // RangeEntry: Iterate over all entry pointers (more efficient)\n    // Note: loaded parameter is guaranteed to be non-nil during iteration\n    cache.RangeEntry(func(loaded *pb.EntryOf[string, int]) bool {\n        fmt.Printf(\"%s: %d\\n\", loaded.Key, loaded.Value)\n        return true\n    })\n\n    // All: Go 1.23+ iterator support\n    for key, value := range cache.All() {\n        fmt.Printf(\"%s: %d\\n\", key, value)\n    }\n}\n```\n\n#### 6. Batch Operations\n\n```go\nimport (\n    \"fmt\"\n    \"maps\"\n    \"github.com/llxisdsh/pb\"\n)\n\nfunc batchOperations() {\n    cache := pb.NewMapOf[string, int]()\n\n    // Batch process all entries\n    // NOTE: loaded parameter is guaranteed to be non-nil during iteration\n    // WriterPolicy options:\n    //   cache.RangeProcessEntry(fn)                  // allow concurrent writes (default)\n    //   cache.RangeProcessEntry(fn, pb.BlockWriters) // block concurrent writes\n    cache.RangeProcessEntry(func(loaded *pb.EntryOf[string, int]) *pb.EntryOf[string, int] {\n        if loaded.Value \u003c 100 {\n            // Double all values less than 100\n            return \u0026pb.EntryOf[string, int]{Value: loaded.Value * 2}\n        }\n        return loaded // Keep unchanged\n    })\n\n\n    // Batch processing with Go 1.23+ iterator syntax\n    // WriterPolicy options:\n    //   cache.ProcessAll()                // allow concurrent writes (default)\n    //   cache.ProcessAll(pb.BlockWriters) // block concurrent writes\n    for e := range cache.ProcessAll() {\n        switch e.Key() {\n        case \"batch1\":\n            e.Update(e.Value() + 500)\n        case \"batch2\":\n            e.Delete()\n        default:\n            // no-op\n        }\n    }\n\n    // Process entries with specified keys (Go 1.23+ iterator support)\n    for e := range cache.ProcessSpecified(\"batch1\", \"batch4\") {\n        if e.Loaded() \u0026\u0026 e.Value() \u003c 1000 {\n            e.Delete()\n        }\n    }\n\n    // Store multiple values\n    batchData := map[string]int{\n        \"batch1\": 1000,\n        \"batch2\": 2000,\n        \"batch3\": 3000,\n    }\n    cache.FromMap(batchData)\n\n    // Load multiple values\n    keys := []string{\"batch1\", \"batch2\", \"nonexistent\"}\n    for _, key := range keys {\n        if value, ok := cache.Load(key); ok {\n            fmt.Printf(\"%s: %d\\n\", key, value)\n        } else {\n            fmt.Printf(\"%s: not found\\n\", key)\n        }\n    }\n\n    // Delete multiple values using BatchDelete\n    cache.BatchDelete([]string{\"batch1\", \"batch2\"})\n\n    // BatchProcess: Batch process iterator data\n    data := map[string]int{\"a\": 1, \"b\": 2, \"c\": 3}\n    cache.BatchProcess(maps.All(data), func(_ string, v int, loaded *pb.EntryOf[string, int]) (*pb.EntryOf[string, int], int, bool) {\n        return \u0026pb.EntryOf[string, int]{Value: v * 10}, v, true\n    })\n}\n```\n\n#### 7. Capacity Management\n\n```go\nimport (\n    \"fmt\"\n    \"github.com/llxisdsh/pb\"\n)\n\nfunc capacityManagement() {\n    cache := pb.NewMapOf[string, int]()\n\n    // Get current size\n    size := cache.Size()\n    fmt.Printf(\"Current size: %d\\n\", size)\n\n    // Check if map is zero-value\n    if cache.IsZero() {\n        fmt.Println(\"Cache is empty\")\n    }\n\n    // Pre-allocate capacity to avoid frequent resizing\n    cache.Grow(10000)\n\n    // Manual shrink\n    cache.Shrink()\n\n    // Clear all entries\n    cache.Clear()\n}\n```\n\n#### 8. Data Conversion and Serialization\n\n```go\nimport (\n    \"encoding/json\"\n    \"fmt\"\n    \"github.com/llxisdsh/pb\"\n)\n\nfunc dataConversionAndSerialization() {\n    cache := pb.NewMapOf[string, int]()\n    cache.Store(\"key1\", 100)\n    cache.Store(\"key2\", 200)\n\n    // Clone: Deep copy the entire map\n    clonedCache := cache.Clone()\n    fmt.Printf(\"Cloned size: %d\\n\", clonedCache.Size())\n\n    // Convert to Go map\n    goMap := cache.ToMap()\n    fmt.Printf(\"Go map: %+v\\n\", goMap)\n\n    // Load from Go map\n    newData := map[string]int{\n        \"new1\": 100,\n        \"new2\": 200,\n    }\n    cache.FromMap(newData)\n\n    // JSON serialization\n    jsonData, err := json.Marshal(\u0026cache)\n    if err == nil {\n        fmt.Printf(\"JSON: %s\\n\", jsonData)\n    }\n\n    // JSON deserialization\n    var newCache pb.MapOf[string, int]\n    err = json.Unmarshal(jsonData, \u0026newCache)\n    if err == nil {\n        fmt.Println(\"Successfully deserialized from JSON\")\n    }\n\n    // String representation\n    fmt.Printf(\"Cache contents: %s\\n\", cache.String())\n\n    // Stats: Get detailed performance statistics\n    stats := cache.Stats()\n    fmt.Printf(\"Stats: Buckets=%d, Growths=%d, Shrinks=%d\\n\",\n        stats.RootBuckets, stats.TotalGrowths, stats.TotalShrinks)\n}\n```\n\n\n### Compile-Time Optimizations\n\nOptimize performance for specific use cases with build tags. Warning: Incorrect optimization choices may degrade performance. Choose carefully based on your actual scenario.\n\n```bash\n# === Cache Line Size Optimization ===\n# Optimize based on target CPU's cache line size\n# Auto-detection is default, but manual specification may be needed for cross-compilation\ngo build -tags mapof_opt_cachelinesize_32   # For some embedded systems\ngo build -tags mapof_opt_cachelinesize_64   # For most modern CPUs\ngo build -tags mapof_opt_cachelinesize_128  # For some high-end server CPUs\ngo build -tags mapof_opt_cachelinesize_256  # For some specialized architectures\n\n# === Counter Performance Optimization ===\n# Add padding around counters to reduce false sharing in high‑concurrency scenarios.\n# By default, padding is selected automatically based on CPU architecture;\n# you can override this behavior via build tags:\ngo build -tags mapof_opt_disablepadding  # Force disable counters padding\ngo build -tags mapof_opt_enablepadding   # Force enable counters padding\n\n# === Hash Caching Optimization ===\n# Cache hash values in entries, suitable for expensive hash computation scenarios\n# Note: Go's built-in hashing is usually fast; this may increase memory overhead without performance gain\ngo build -tags mapof_opt_embeddedhash\n\n# === Combined Optimization Examples ===\n\n# Build with optimizations for FUJITSU A64FX's CMG-based ccNUMA architecture:\ngo build -tags \"mapof_opt_cachelinesize_256 mapof_opt_enablepadding\"\n\n# Complex key types configuration:\ngo build -tags \"mapof_opt_embeddedhash\"\n```\n\nOptimization Selection Guide:\n\n- Default Configuration : Suitable for most scenarios, no additional tags needed\n- NUMA architecture: Consider mapof_opt_enablepadding\n- Complex Key Types : If hash computation is expensive, consider mapof_opt_embeddedhash\n- Cross-Compilation : May need manual mapof_opt_cachelinesize_* specification\n  Performance Testing Recommendation: Before production use, benchmark different optimization combinations against your specific workload to determine the best configuration.\n\n## 📚 Documentation\n\n- Complete API documentation is available at [pkg.go.dev/github.com/llxisdsh/pb](https://pkg.go.dev/github.com/llxisdsh/pb)\n\n- See [mapof flow](mapof_flow.md) for implementation details.\n\n\n## 🙏 Acknowledgments\n\npb.MapOf builds upon the excellent work of [xsync](https://github.com/puzpuzpuz/xsync)(v3, MIT licensed). We extend our gratitude to the xsync authors and the broader Go community.\nReproduce its introduction below:\n\n```\nMapOf is like a Go map[K]V but is safe for concurrent\nuse by multiple goroutines without additional locking or\ncoordination. It follows the interface of sync.Map with\na number of valuable extensions like Compute or Size.\n\nA MapOf must not be copied after first use.\n\nMapOf uses a modified version of Cache-Line Hash Table (CLHT)\ndata structure: https://github.com/LPD-EPFL/CLHT\n\nCLHT is built around idea to organize the hash table in\ncache-line-sized buckets, so that on all modern CPUs update\noperations complete with at most one cache-line transfer.\nAlso, Get operations involve no write to memory, as well as no\nmutexes or any other sort of locks. Due to this design, in all\nconsidered scenarios MapOf outperforms sync.Map.\n\nMapOf also borrows ideas from Java's j.u.c.ConcurrentHashMap\n(immutable K/V pair structs instead of atomic snapshots)\nand C++'s absl::flat_hash_map (meta memory and SWAR-based lookups).\n```\n\n---\n\n# FlatMapOf\n\nFlatMapOf is a seqlock-based, flat-layout concurrent hash table. The table and key/value entries are stored inline to minimize pointer chasing and cache misses, providing more stable latency and throughput even for cold working sets.\n\nDesign and concurrency semantics (overview)\n- Read path (seqlock validation): Each bucket maintains a sequence. Readers load s1; if s1 is even, they read metadata/entries and then load s2. If s1==s2 (and even), the read is consistent; otherwise, readers spin and retry.\n- Write path (ordered publication): While holding the root-bucket lock (opLock), flip the bucket sequence to odd (enter write state) → apply modifications → flip back to even (publish a consistent view), and finally release the root lock.\n- Resizing (parallel copy): A help–copy–publish protocol partitions the table and migrates buckets in parallel. When migration completes, the new table is atomically published. Ongoing reads/writes are minimally affected.\n\nMemory layout and cache behavior\n- Inlined K/V entries: Entries are laid out contiguously with their bucket, reducing extra pointer dereferences and cross-line accesses. Under cold data and low cache-hit scenarios, this significantly reduces p99/p999 latency jitter.\n- Value size: V is not limited by machine word size; any value type is supported. Note that large V increases the per-bucket footprint (see “Limitations”).\n\nTime and space characteristics (intuition)\n- Load/Store: amortized O(1) under uniform hashing and reasonable load.\n- Progress: reads lock-free without contention; under contention, spin + backoff; writes use bucket-level mutual exclusion.\n- Latency: inline layout reduces pointer chasing and improves p99/p999 stability on cold sets.\n\nSystematic comparison with MapOf\n- Concurrency control model:\n  - FlatMapOf: bucket-level seqlock + root-bucket mutual exclusion; reads are “optimistic + sequence validation,” writes are “odd/even sequence toggle + ordered publication.”\n  - MapOf: CLHT-inspired design; read path performs no writes (lock-free) and uses SWAR metadata for fast matching; writes use fine-grained synchronization at the bucket level.\n- Read latency and cold data:\n  - FlatMapOf: the inline layout avoids multi-hop pointer chasing under cold states, yielding more predictable hit latency and smoother tail latency.\n  - MapOf: extremely fast for hot data; with colder data and more cross-object pointer traversals, latency stability can be slightly worse than FlatMapOf.\n- Writes and contention:\n  - FlatMapOf: writes toggle bucket sequences and hold the root lock; under sustained high write contention, reads may experience bounded retries, and throughput may degrade earlier than in a read-optimized MapOf.\n  - MapOf: pointer-level updates with a mature write path; often easier to sustain throughput in write-heavy scenarios.\n- Memory footprint and density:\n  - FlatMapOf: inline entries avoid “one allocation per entry,” but incur “hole cost” (reserved space in partially filled buckets); when V is large or occupancy is sparse, bucket size inflation increases baseline memory usage.\n  - MapOf: buckets store pointers and entries are separate objects; with automatic shrinking (WithShrinkEnabled), MapOf is typically more memory-elastic and efficient, especially for large V or underutilized tables.\n- API capabilities and ecosystem:\n  - FlatMapOf: it does not currently offer dedicated convenience APIs such as CompareAndSwap/CompareAndDelete, but such semantics can be expressed using Process.\n  - MapOf: a more complete API surface including multiple CompareAnd*, and batch operations, plus richer customization of equality and hashing, making it more mature for migration and production use.\n- Hashing and optimizations:\n  - Both support WithKeyHasher/IHashCode; FlatMapOf also supports WithPresize and WithShrinkEnabled.\n\nAdvantages (FlatMapOf)\n- More stable hit latency and tail behavior in cold working sets and random-access workloads.\n- Inline layout reduces pointer chasing and cache misses; Range/scan-style operations benefit from better sequential locality.\n- Parallel resize support; arbitrary value sizes are supported.\n\nLimitations and caveats (FlatMapOf)\n- Large V or sparse occupancy amplifies the “hole cost,” increasing memory consumption.\n- Under sustained write contention with longer critical sections, reads may retry, reducing throughput.\n- Dedicated CompareAnd* convenience APIs are currently unavailable; use Process to compose equivalent atomic semantics.\n\nUsage guidance and boundaries\n- Prefer FlatMapOf for:\n  - Read-dominant or mixed workloads with strong p99/p999 latency requirements on the online path;\n  - Cold or low-cache-hit distributions where predictable hit latency is critical;\n  - Small-to-medium value types where modest space trade-offs improve latency and throughput;\n  - Range/scan tasks that benefit from improved sequential locality.\n- Prefer MapOf for:\n  - Memory efficiency under resource constraints, or large value types with sparse occupancy;\n  - Write-heavy or high-contention workloads where a more mature write path is desirable.\n\nAPI overview\n- Provided: Load, Store, Delete, LoadOrStore, LoadOrStoreFn, LoadAndDelete, LoadAndUpdate, Swap, Range, Process, RangeProcess, Clear, Size, IsZero.\n- Compositional semantics: Process can express atomic read-modify-write, conditional updates, and conditional deletes.\n- Construction and configuration: supports zero-initialization; supports WithPresize and WithShrinkEnabled for capacity and shrinking; supports custom hashing and distribution via IHashCode/WithKeyHasher.\n\n---\n\n# HashTrieMap\n\n\n**HashTrieMap** is a highly optimized implementation of Go's built-in `HashTrieMap`, delivering **50%+ performance improvements** while maintaining full compatibility.\n\n## 🎯 Key Improvements\n\n- **Lazy Value Generation**: `LoadOrStoreFn` support for expensive computations\n- **50%+ Performance Gain**: Optimized initialization and atomic operations\n- **Full Compatibility**: Drop-in replacement for built-in HashTrieMap\n- **Comprehensive Testing**: All original tests pass plus additional validation\n\n## 🔧 Technical Optimizations\n\n- **Eliminated `inited` Field**: Uses root pointer directly for state management\n- **Lazy Initialization**: Defers initialization until first write operation\n- **Hash Caching**: Caches hash values to accelerate expand operations\n\n---\n\n# 📄 License\n\nLicensed under [MIT License](LICENSE).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fllxisdsh%2Fpb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fllxisdsh%2Fpb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fllxisdsh%2Fpb/lists"}