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

[Performance] Investigate and decrease RAM usage - add pebble kvstore #52

Merged
merged 12 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ test_all: ## runs the test suite
test_badger: ## runs the badger KVStore submodule's test suite
go test -v -p 1 -count=1 ./kvstore/badger/... -mod=readonly -race

.PHONY: test_pebble
test_pebble: ## runs the pebble KVStore submodule's test suite
okdas marked this conversation as resolved.
Show resolved Hide resolved
go test -v -p 1 -count=1 ./kvstore/pebble/... -mod=readonly -race


#####################
### go helpers ###
Expand Down Expand Up @@ -93,6 +97,10 @@ benchmark_smst_ops: ## runs the benchmarks test different operations on the SMS
benchmark_proof_sizes: ## runs the benchmarks test the proof sizes for different sized tries
go test -tags=benchmark -v ./benchmarks -run ProofSizes

.PHONY: benchmark_pebble
benchmark_pebble: ## TODO: Add the pebble benchmarks
echo "TODO: Implement pebble benchmarks"

###########################
### Release Helpers ###
###########################
Expand Down Expand Up @@ -120,4 +128,4 @@ tag_minor_release: ## Tag a new minor release (e.g. v1.0.0 -> v1.1.0)
@echo "New minor release version tagged: $(NEW_TAG)"
@echo "Run the following commands to push the new tag:"
@echo " git push origin $(NEW_TAG)"
@echo "And draft a new release at https://github.com/pokt-network/smt/releases/new"
@echo "And draft a new release at https://github.com/pokt-network/smt/releases/new"
10 changes: 6 additions & 4 deletions go.work
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
go 1.20

use (
// Include the main SMT module
.
// Include the badger KVStore submodule
./kvstore/badger
// Include the main SMT module
.
// Include the badger KVStore submodule
./kvstore/badger
// Include the pebble KVStore submodule
./kvstore/pebble
)
82 changes: 75 additions & 7 deletions go.work.sum
Original file line number Diff line number Diff line change
@@ -1,43 +1,111 @@
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
github.com/CloudyKit/jet/v6 v6.2.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4=
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM=
github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM=
github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794/go.mod h1:7e+I0LQFUI9AXWxOfsQROs9xPhoJtbsyWcjJqDd4KPY=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8=
github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4=
github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
github.com/guptarohit/asciigraph v0.5.5/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag=
github.com/hydrogen18/memlistener v1.0.0/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I=
github.com/kataras/golog v0.1.8/go.mod h1:rGPAin4hYROfk1qT9wZP6VY2rsb4zzc37QpdPjdkqVw=
github.com/kataras/iris/v12 v12.2.0/go.mod h1:BLzBpEunc41GbE68OUaQlqX4jzi791mx5HU04uPb90Y=
github.com/kataras/pio v0.0.11/go.mod h1:38hH6SWH6m4DKSYmRhlrCJ5WItwWgCVrTNU62XZyUvI=
github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4=
github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw=
github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
github.com/labstack/echo/v4 v4.10.0/go.mod h1:S/T/5fy/GigaXnHTkh0ZGe4LpkkQysvRjFMSUTkDRNQ=
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4=
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/tdewolff/minify/v2 v2.12.4/go.mod h1:h+SRvSIX3kwgwTFOpSckvSxgax3uy8kZTSF1Ojrr3bk=
github.com/tdewolff/parse/v2 v2.6.4/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0=
github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099 h1:XJP7lxbSxWLOMNdBE4B/STaqVy6L73o0knwj2vIlxnw=
3 changes: 3 additions & 0 deletions kvstore/badger/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,7 @@ var (
// ErrBadgerGettingStoreLength is returned when the badger store fails to
// get the length of the database
ErrBadgerGettingStoreLength = errors.New("unable to get database length")
// ErrBadgerUnableToCheckExistence is returned when the badger store fails to
// check if a key exists
ErrBadgerUnableToCheckExistence = errors.New("unable to check key existence")
)
16 changes: 1 addition & 15 deletions kvstore/badger/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,7 @@ var _ kvstore.MapStore = (BadgerKVStore)(nil)
// This is a superset of the MapStore interface that offers more
// features and can be used as a standalone key-value store.
type BadgerKVStore interface {
// --- Store methods ---

// Get returns the value for a given key
Get(key []byte) ([]byte, error)
// Set sets/updates the value for a given key
Set(key, value []byte) error
// Delete removes a key
Delete(key []byte) error
kvstore.MapStore

// --- Lifecycle methods ---

Expand All @@ -41,11 +34,4 @@ type BadgerKVStore interface {
GetAll(prefixKey []byte, descending bool) (keys, values [][]byte, err error)
// Exists returns true if the key exists
Exists(key []byte) (bool, error)
// Len returns the number of key-value pairs in the store
Len() int

// --- Data management ---

// ClearAll deletes all key-value pairs in the store
ClearAll() error
}
57 changes: 45 additions & 12 deletions kvstore/badger/kvstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type badgerKVStore struct {

// NewKVStore creates a new BadgerKVStore using badger as the underlying database
// if no path for a persistence database is provided it will create one in-memory
// TODO_CONSIDERATION: consider exposing the low-level options (`badgerv4.Options`) via a
// config file to make it easier to test under different load conditions.
func NewKVStore(path string) (BadgerKVStore, error) {
var db *badgerv4.DB
var err error
Expand All @@ -31,6 +33,7 @@ func NewKVStore(path string) (BadgerKVStore, error) {
if err != nil {
return nil, errors.Join(ErrBadgerOpeningStore, err)
}

return &badgerKVStore{db: db}, nil
}

Expand Down Expand Up @@ -109,13 +112,26 @@ func (store *badgerKVStore) GetAll(prefix []byte, descending bool) (keys, values
return keys, values, nil
}

// Exists checks whether the key exists in the store
// Exists checks whether the key exists in the store without retrieving the full value.
// This avoids unnecessary memory allocations and copying that would occur with a full Get.
func (store *badgerKVStore) Exists(key []byte) (bool, error) {
val, err := store.Get(key)
var exists bool
err := store.db.View(func(tx *badgerv4.Txn) error {
okdas marked this conversation as resolved.
Show resolved Hide resolved
item, err := tx.Get(key)
if err != nil {
return err
}
// Check if the value is nil
err = item.Value(func(val []byte) error {
exists = len(val) > 0
return nil
})
return err
})
if err != nil {
return false, err
return false, errors.Join(ErrBadgerUnableToCheckExistence, err)
}
return val != nil, nil
return exists, nil
}

// ClearAll deletes all key-value pairs in the store
Expand Down Expand Up @@ -159,9 +175,9 @@ func (store *badgerKVStore) Stop() error {
}

// Len gives the number of keys in the store
func (store *badgerKVStore) Len() int {
count := 0
if err := store.db.View(func(tx *badgerv4.Txn) error {
func (store *badgerKVStore) Len() (int, error) {
var count int
err := store.db.View(func(tx *badgerv4.Txn) error {
opt := badgerv4.DefaultIteratorOptions
opt.Prefix = []byte{}
opt.Reverse = false
Expand All @@ -171,14 +187,22 @@ func (store *badgerKVStore) Len() int {
count++
}
return nil
}); err != nil {
panic(errors.Join(ErrBadgerGettingStoreLength, err))
})
if err != nil {
return 0, errors.Join(ErrBadgerGettingStoreLength, err)
}
return count
return count, nil
}

// PrefixEndBytes returns the end byteslice for a noninclusive range
// that would include all byte slices for which the input is the prefix
// prefixEndBytes returns the end byteslice for a noninclusive range
// that would include all byte slices for which the input is the prefix.
// It's used in reverse iteration to set the upper bound of the key range.
//
// Example:
// If prefix is []byte("user:1"), prefixEndBytes returns []byte("user:2").
// This ensures that in reverse iteration:
// - Keys like "user:1", "user:1:profile", "user:10" are included.
// - But "user:2", "user:2:profile" are not included.
func prefixEndBytes(prefix []byte) []byte {
if len(prefix) == 0 {
return nil
Expand All @@ -194,7 +218,16 @@ func prefixEndBytes(prefix []byte) []byte {

// badgerOptions returns the badger options for the store being created
func badgerOptions(path string) badgerv4.Options {
// DEV_NOTE: Parameters should be adjusted carefully, depending on the type of load. We need to experiment more to find the best
// values, and even then they might need further adjustments as the type of load/environment (e.g. memory dedicated
// to the process) changes.
//
// Good links to read about options:
// - https://github.com/dgraph-io/badger/issues/1304#issuecomment-630078745
// - https://github.com/dgraph-io/badger/blob/master/options.go#L37
// - https://github.com/open-policy-agent/opa/issues/4014#issuecomment-1003700744
opts := badgerv4.DefaultOptions(path)
opts.Logger = nil // disable badger's logger since it's very noisy

return opts
}
7 changes: 5 additions & 2 deletions kvstore/badger/kvstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/stretchr/testify/require"

badgerv4 "github.com/dgraph-io/badger/v4"
"github.com/pokt-network/smt/kvstore/badger"
)

Expand Down Expand Up @@ -280,7 +281,7 @@ func TestBadger_KVStore_Exists(t *testing.T) {

// Key does not exist
exists, err = store.Exists([]byte("oof"))
require.ErrorIs(t, err, badger.ErrBadgerUnableToGetValue)
require.ErrorIs(t, err, badgerv4.ErrKeyNotFound)
require.False(t, exists)

err = store.Stop()
Expand Down Expand Up @@ -389,7 +390,9 @@ func TestBadger_KVStore_Len(t *testing.T) {

for _, tc := range tests {
require.NoError(t, store.Set(tc.key, tc.value))
require.Equal(t, tc.size, store.Len())
len, err := store.Len()
require.NoError(t, err)
require.Equal(t, tc.size, len)
}
}

Expand Down
2 changes: 1 addition & 1 deletion kvstore/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type MapStore interface {
// Delete removes a key
Delete(key []byte) error
// Len returns the number of key-value pairs in the store
Len() int
Len() (int, error)

// --- Debug ---

Expand Down
36 changes: 36 additions & 0 deletions kvstore/pebble/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package pebble

import "errors"

// Error definitions
var (
// ErrPebbleOpeningStore is returned when there's an error opening the Pebble database.
ErrPebbleOpeningStore = errors.New("error opening the store")

// ErrPebbleUnableToSetValue is returned when a value cannot be set in the store.
ErrPebbleUnableToSetValue = errors.New("unable to set value")

// ErrPebbleUnableToGetValue is returned when a value cannot be retrieved from the store.
ErrPebbleUnableToGetValue = errors.New("unable to get value")

// ErrPebbleUnableToDeleteValue is returned when a value cannot be deleted from the store.
ErrPebbleUnableToDeleteValue = errors.New("unable to delete value")

// ErrPebbleIteratingStore is returned when there's an error iterating over the database.
ErrPebbleIteratingStore = errors.New("unable to iterate over database")

// ErrPebbleClearingStore is returned when there's an error clearing all data from the store.
ErrPebbleClearingStore = errors.New("unable to clear store")

// ErrPebbleUnableToBackup is returned when there's an error backing up the database.
ErrPebbleUnableToBackup = errors.New("unable to backup database")

// ErrPebbleUnableToRestore is returned when there's an error restoring the database from a backup.
ErrPebbleUnableToRestore = errors.New("unable to restore database")

// ErrPebbleClosingStore is returned when there's an error closing the database connection.
ErrPebbleClosingStore = errors.New("unable to close database")

// ErrPebbleGettingStoreLength is returned when there's an error getting the number of key-value pairs in the database.
ErrPebbleGettingStoreLength = errors.New("unable to get database length")
)
Loading
Loading