mirror of
				https://github.com/nalgeon/redka.git
				synced 2025-10-31 03:16:28 +08:00 
			
		
		
		
	refactor: use vfs=memdb instead of mode=memory&cache=shared
Shared cache is discouraged. The supported alternative (and increasingly recommended by SQLite developers), is the memdb VFS (which I believe is supported by all drivers). I'm sure modernc has it, and mattn also does if compiled with SQLITE_ENABLE_DESERIALIZE, which became the default in 2021. https://github.com/ncruces/go-sqlite3/issues/94#issuecomment-2157679766
This commit is contained in:
		| @@ -13,7 +13,7 @@ import ( | |||||||
| 	"github.com/nalgeon/redka/internal/redis" | 	"github.com/nalgeon/redka/internal/redis" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const dbURI = ":memory:" | const dbURI = "file:/data.db?vfs=memdb" | ||||||
|  |  | ||||||
| func init() { | func init() { | ||||||
| 	flag.Usage = func() { | 	flag.Usage = func() { | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ var ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| const driverName = "redka" | const driverName = "redka" | ||||||
| const memoryURI = "file:redka?mode=memory&cache=shared" | const memoryURI = "file:/data.db?vfs=memdb" | ||||||
| const pragma = ` | const pragma = ` | ||||||
| pragma journal_mode = wal; | pragma journal_mode = wal; | ||||||
| pragma synchronous = normal; | pragma synchronous = normal; | ||||||
|   | |||||||
| @@ -35,8 +35,8 @@ Redka (in-memory): | |||||||
| ./redka -p 6380 | ./redka -p 6380 | ||||||
| redis-benchmark -p 6380 -q -c 10 -n 1000000 -r 10000 -t get,set | redis-benchmark -p 6380 -q -c 10 -n 1000000 -r 10000 -t get,set | ||||||
|  |  | ||||||
| SET: 34927.18 requests per second, p50=0.175 msec | SET: 36188.62  requests per second, p50=0.167 msec | ||||||
| GET: 52173.01 requests per second, p50=0.143 msec | GET: 104405.93 requests per second, p50=0.063 msec | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Redka (persisted to disk): | Redka (persisted to disk): | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ To open an in-memory database that doesn't persist to disk, use the following pa | |||||||
|  |  | ||||||
| ```go | ```go | ||||||
| // All data is lost when the database is closed. | // All data is lost when the database is closed. | ||||||
| redka.Open("file:redka?mode=memory&cache=shared") | redka.Open("file:/data.db?vfs=memdb") | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| After opening the database, call `redka.DB` methods to run individual commands: | After opening the database, call `redka.DB` methods to run individual commands: | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import ( | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import ( | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import ( | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import ( | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import ( | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ import ( | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import ( | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ import ( | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | func getDB(tb testing.TB) (*redka.DB, redis.Redka) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -875,7 +875,7 @@ func TestValues(t *testing.T) { | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, *rhash.DB) { | func getDB(tb testing.TB) (*redka.DB, *rhash.DB) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -610,7 +610,7 @@ func TestScanner(t *testing.T) { | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, *rkey.DB) { | func getDB(tb testing.TB) (*redka.DB, *rkey.DB) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -1454,7 +1454,7 @@ func TestTrim(t *testing.T) { | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, *rlist.DB) { | func getDB(tb testing.TB) (*redka.DB, *rlist.DB) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -1298,7 +1298,7 @@ func TestUnionStore(t *testing.T) { | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, *rset.DB) { | func getDB(tb testing.TB) (*redka.DB, *rset.DB) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -821,7 +821,7 @@ func TestSetNotExists(t *testing.T) { | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, *rstring.DB) { | func getDB(tb testing.TB) (*redka.DB, *rstring.DB) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -1584,7 +1584,7 @@ func TestUnionStore(t *testing.T) { | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) (*redka.DB, *rzset.DB) { | func getDB(tb testing.TB) (*redka.DB, *rzset.DB) { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func TestHandlers(t *testing.T) { | func TestHandlers(t *testing.T) { | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func ExampleOpen() { | func ExampleOpen() { | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
| @@ -21,7 +21,7 @@ func ExampleOpen() { | |||||||
| } | } | ||||||
|  |  | ||||||
| func ExampleDB_Close() { | func ExampleDB_Close() { | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
| @@ -33,7 +33,7 @@ func ExampleDB_Hash() { | |||||||
| 	// Error handling is omitted for brevity. | 	// Error handling is omitted for brevity. | ||||||
| 	// In real code, always check for errors. | 	// In real code, always check for errors. | ||||||
|  |  | ||||||
| 	db, _ := redka.Open(":memory:", nil) | 	db, _ := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	defer db.Close() | 	defer db.Close() | ||||||
|  |  | ||||||
| 	ok, err := db.Hash().Set("user:1", "name", "alice") | 	ok, err := db.Hash().Set("user:1", "name", "alice") | ||||||
| @@ -57,7 +57,7 @@ func ExampleDB_Key() { | |||||||
| 	// Error handling is omitted for brevity. | 	// Error handling is omitted for brevity. | ||||||
| 	// In real code, always check for errors. | 	// In real code, always check for errors. | ||||||
|  |  | ||||||
| 	db, _ := redka.Open(":memory:", nil) | 	db, _ := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	defer db.Close() | 	defer db.Close() | ||||||
|  |  | ||||||
| 	_ = db.Str().SetExpires("name", "alice", 60*time.Second) | 	_ = db.Str().SetExpires("name", "alice", 60*time.Second) | ||||||
| @@ -79,7 +79,7 @@ func ExampleDB_Str() { | |||||||
| 	// Error handling is omitted for brevity. | 	// Error handling is omitted for brevity. | ||||||
| 	// In real code, always check for errors. | 	// In real code, always check for errors. | ||||||
|  |  | ||||||
| 	db, _ := redka.Open(":memory:", nil) | 	db, _ := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	defer db.Close() | 	defer db.Close() | ||||||
|  |  | ||||||
| 	_ = db.Str().Set("name", "alice") | 	_ = db.Str().Set("name", "alice") | ||||||
| @@ -99,7 +99,7 @@ func ExampleDB_ZSet() { | |||||||
| 	// Error handling is omitted for brevity. | 	// Error handling is omitted for brevity. | ||||||
| 	// In real code, always check for errors. | 	// In real code, always check for errors. | ||||||
|  |  | ||||||
| 	db, _ := redka.Open(":memory:", nil) | 	db, _ := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	defer db.Close() | 	defer db.Close() | ||||||
|  |  | ||||||
| 	ok, err := db.ZSet().Add("race", "alice", 11) | 	ok, err := db.ZSet().Add("race", "alice", 11) | ||||||
| @@ -121,7 +121,7 @@ func ExampleDB_ZSet() { | |||||||
| } | } | ||||||
|  |  | ||||||
| func ExampleDB_Update() { | func ExampleDB_Update() { | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic(err) | 		panic(err) | ||||||
| 	} | 	} | ||||||
| @@ -153,7 +153,7 @@ func ExampleDB_View() { | |||||||
| 	// Error handling is omitted for brevity. | 	// Error handling is omitted for brevity. | ||||||
| 	// In real code, always check for errors. | 	// In real code, always check for errors. | ||||||
|  |  | ||||||
| 	db, _ := redka.Open(":memory:", nil) | 	db, _ := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	defer db.Close() | 	defer db.Close() | ||||||
|  |  | ||||||
| 	_ = db.Str().SetMany(map[string]any{ | 	_ = db.Str().SetMany(map[string]any{ | ||||||
| @@ -190,7 +190,7 @@ func ExampleDB_View() { | |||||||
| } | } | ||||||
|  |  | ||||||
| func TestOpenDB(t *testing.T) { | func TestOpenDB(t *testing.T) { | ||||||
| 	sdb, err := sql.Open("sqlite3", ":memory:") | 	sdb, err := sql.Open("sqlite3", "file:/data.db?vfs=memdb") | ||||||
| 	testx.AssertNoErr(t, err) | 	testx.AssertNoErr(t, err) | ||||||
|  |  | ||||||
| 	db, err := redka.OpenDB(sdb, sdb, nil) | 	db, err := redka.OpenDB(sdb, sdb, nil) | ||||||
| @@ -282,7 +282,7 @@ func TestDBUpdateRollback(t *testing.T) { | |||||||
|  |  | ||||||
| func getDB(tb testing.TB) *redka.DB { | func getDB(tb testing.TB) *redka.DB { | ||||||
| 	tb.Helper() | 	tb.Helper() | ||||||
| 	db, err := redka.Open(":memory:", nil) | 	db, err := redka.Open("file:/data.db?vfs=memdb", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		tb.Fatal(err) | 		tb.Fatal(err) | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Anton
					Anton