github.com/TeaOSLab/EdgeNode@v1.3.8/internal/utils/kvstore/query_test.go (about)

     1  // Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
     2  
     3  package kvstore_test
     4  
     5  import (
     6  	"fmt"
     7  	"github.com/TeaOSLab/EdgeNode/internal/utils/kvstore"
     8  	"github.com/TeaOSLab/EdgeNode/internal/utils/testutils"
     9  	"runtime"
    10  	"testing"
    11  	"time"
    12  )
    13  
    14  func TestQuery_FindAll(t *testing.T) {
    15  	var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{})
    16  
    17  	defer func() {
    18  		_ = testingStore.Close()
    19  	}()
    20  
    21  	var before = time.Now()
    22  	defer func() {
    23  		t.Log("cost:", time.Since(before).Seconds()*1000, "ms")
    24  	}()
    25  
    26  	err := table.
    27  		Query().
    28  		Limit(10).
    29  		//Offset("a1000").
    30  		//Desc().
    31  		FindAll(func(tx *kvstore.Tx[*testCachedItem], item kvstore.Item[*testCachedItem]) (goNext bool, err error) {
    32  			t.Log("key:", item.Key, "value:", item.Value)
    33  
    34  			return true, nil
    35  		})
    36  	if err != nil {
    37  		t.Fatal(err)
    38  	}
    39  }
    40  
    41  func TestQuery_FindAll_Break(t *testing.T) {
    42  	var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{})
    43  
    44  	defer func() {
    45  		_ = testingStore.Close()
    46  	}()
    47  
    48  	var before = time.Now()
    49  	defer func() {
    50  		t.Log("cost:", time.Since(before).Seconds()*1000, "ms")
    51  	}()
    52  
    53  	var count int
    54  	err := table.
    55  		Query().
    56  		FindAll(func(tx *kvstore.Tx[*testCachedItem], item kvstore.Item[*testCachedItem]) (goNext bool, err error) {
    57  			t.Log("key:", item.Key, "value:", item.Value)
    58  			count++
    59  
    60  			if count > 2 {
    61  				// break test
    62  				_ = table.DB().Store().Close()
    63  			}
    64  
    65  			return count < 3, nil
    66  		})
    67  	if err != nil {
    68  		t.Log(err)
    69  	}
    70  }
    71  
    72  func TestQuery_FindAll_Break_Closed(t *testing.T) {
    73  	var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{})
    74  
    75  	defer func() {
    76  		_ = testingStore.Close()
    77  	}()
    78  
    79  	var before = time.Now()
    80  	defer func() {
    81  		t.Log("cost:", time.Since(before).Seconds()*1000, "ms")
    82  	}()
    83  
    84  	var count int
    85  	err := table.
    86  		Query().
    87  		FindAll(func(tx *kvstore.Tx[*testCachedItem], item kvstore.Item[*testCachedItem]) (goNext bool, err error) {
    88  			t.Log("key:", item.Key, "value:", item.Value)
    89  			count++
    90  
    91  			if count > 2 {
    92  				// break test
    93  				_ = table.DB().Store().Close()
    94  			}
    95  
    96  			return count < 3, nil
    97  		})
    98  	t.Log("expected error:", err)
    99  }
   100  
   101  func TestQuery_FindAll_Desc(t *testing.T) {
   102  	var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{})
   103  
   104  	defer func() {
   105  		_ = testingStore.Close()
   106  	}()
   107  
   108  	err := table.Query().
   109  		Desc().
   110  		Limit(10).
   111  		FindAll(func(tx *kvstore.Tx[*testCachedItem], item kvstore.Item[*testCachedItem]) (goNext bool, err error) {
   112  			t.Log("key:", item.Key, "value:", item.Value)
   113  			return true, nil
   114  		})
   115  	if err != nil {
   116  		t.Fatal(err)
   117  	}
   118  }
   119  
   120  func TestQuery_FindAll_Offset(t *testing.T) {
   121  	var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{})
   122  
   123  	defer func() {
   124  		_ = testingStore.Close()
   125  	}()
   126  
   127  	{
   128  		t.Log("=== forward ===")
   129  		err := table.Query().
   130  			Offset("a3").
   131  			Limit(10).
   132  			FindAll(func(tx *kvstore.Tx[*testCachedItem], item kvstore.Item[*testCachedItem]) (goNext bool, err error) {
   133  				t.Log("key:", item.Key, "value:", item.Value)
   134  				return true, nil
   135  			})
   136  		if err != nil {
   137  			t.Fatal(err)
   138  		}
   139  	}
   140  
   141  	{
   142  		t.Log("=== backward ===")
   143  		err := table.Query().
   144  			Desc().
   145  			Offset("a3").
   146  			Limit(10).
   147  			//KeyOnly().
   148  			FindAll(func(tx *kvstore.Tx[*testCachedItem], item kvstore.Item[*testCachedItem]) (goNext bool, err error) {
   149  				t.Log("key:", item.Key, "value:", item.Value)
   150  				return true, nil
   151  			})
   152  		if err != nil {
   153  			t.Fatal(err)
   154  		}
   155  	}
   156  }
   157  
   158  func TestQuery_FindAll_Skip(t *testing.T) {
   159  	var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{})
   160  
   161  	defer func() {
   162  		_ = testingStore.Close()
   163  	}()
   164  
   165  	{
   166  		err := table.Query().
   167  			Offset("a3").
   168  			Limit(10).
   169  			FindAll(func(tx *kvstore.Tx[*testCachedItem], item kvstore.Item[*testCachedItem]) (goNext bool, err error) {
   170  				if item.Key == "a30" || item.Key == "a3000005" {
   171  					return kvstore.Skip()
   172  				}
   173  				t.Log("key:", item.Key, "value:", item.Value)
   174  				return true, nil
   175  			})
   176  		if err != nil {
   177  			t.Fatal(err)
   178  		}
   179  	}
   180  }
   181  
   182  func TestQuery_FindAll_Count(t *testing.T) {
   183  	var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{})
   184  
   185  	defer func() {
   186  		_ = testingStore.Close()
   187  	}()
   188  
   189  	var count int
   190  
   191  	var before = time.Now()
   192  	defer func() {
   193  		var costSeconds = time.Since(before).Seconds()
   194  		t.Log("cost:", costSeconds*1000, "ms", "qps:", fmt.Sprintf("%.2fM/s", float64(count)/costSeconds/1_000_000))
   195  	}()
   196  
   197  	err := table.
   198  		Query().
   199  		KeysOnly().
   200  		FindAll(func(tx *kvstore.Tx[*testCachedItem], item kvstore.Item[*testCachedItem]) (goNext bool, err error) {
   201  			count++
   202  			return true, nil
   203  		})
   204  	if err != nil {
   205  		t.Fatal(err)
   206  	}
   207  
   208  	t.Log("count:", count)
   209  }
   210  
   211  func TestQuery_FindAll_Field(t *testing.T) {
   212  	var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{})
   213  
   214  	defer func() {
   215  		_ = testingStore.Close()
   216  	}()
   217  
   218  	var before = time.Now()
   219  	defer func() {
   220  		var costSeconds = time.Since(before).Seconds()
   221  		t.Log("cost:", costSeconds*1000, "ms", "qps:", int(1/costSeconds))
   222  	}()
   223  
   224  	var lastFieldKey []byte
   225  
   226  	t.Log("=======")
   227  	{
   228  		err := table.
   229  			Query().
   230  			FieldAsc("expiresAt").
   231  			//KeysOnly().
   232  			//FieldLt(1710848959).
   233  			Limit(3).
   234  			FindAll(func(tx *kvstore.Tx[*testCachedItem], item kvstore.Item[*testCachedItem]) (goNext bool, err error) {
   235  				t.Log(item.Key, "=>", item.Value)
   236  				lastFieldKey = item.FieldKey
   237  				return true, nil
   238  			})
   239  		if err != nil {
   240  			t.Fatal(err)
   241  		}
   242  
   243  	}
   244  
   245  	t.Log("=======")
   246  	{
   247  		err := table.
   248  			Query().
   249  			FieldAsc("expiresAt").
   250  			//KeysOnly().
   251  			//FieldLt(1710848959).
   252  			FieldOffset(lastFieldKey).
   253  			Limit(3).
   254  			FindAll(func(tx *kvstore.Tx[*testCachedItem], item kvstore.Item[*testCachedItem]) (goNext bool, err error) {
   255  				t.Log(item.Key, "=>", item.Value)
   256  				lastFieldKey = item.FieldKey
   257  				return true, nil
   258  			})
   259  		if err != nil {
   260  			t.Fatal(err)
   261  		}
   262  	}
   263  }
   264  
   265  func TestQuery_FindAll_Field_Many(t *testing.T) {
   266  	var table = testOpenStoreTable[*testCachedItem](t, "cache_items", &testCacheItemEncoder[*testCachedItem]{})
   267  
   268  	defer func() {
   269  		_ = testingStore.Close()
   270  	}()
   271  
   272  	var before = time.Now()
   273  	defer func() {
   274  		var costSeconds = time.Since(before).Seconds()
   275  		t.Log("cost:", costSeconds*1000, "ms", "qps:", int(1/costSeconds))
   276  	}()
   277  
   278  	var count = 3
   279  	if testutils.IsSingleTesting() {
   280  		count = 1_000
   281  	}
   282  
   283  	err := table.
   284  		Query().
   285  		FieldAsc("expiresAt").
   286  		KeysOnly().
   287  		Limit(count).
   288  		FindAll(func(tx *kvstore.Tx[*testCachedItem], item kvstore.Item[*testCachedItem]) (goNext bool, err error) {
   289  			t.Log(item.Key, "=>", item.Value)
   290  			return true, nil
   291  		})
   292  	if err != nil {
   293  		t.Fatal(err)
   294  	}
   295  }
   296  
   297  func BenchmarkQuery_FindAll(b *testing.B) {
   298  	runtime.GOMAXPROCS(4)
   299  
   300  	store, err := kvstore.OpenStore("test")
   301  	if err != nil {
   302  		b.Fatal(err)
   303  	}
   304  	defer func() {
   305  		_ = store.Close()
   306  	}()
   307  
   308  	db, err := store.NewDB("db1")
   309  	if err != nil {
   310  		b.Fatal(err)
   311  	}
   312  
   313  	table, err := kvstore.NewTable[*testCachedItem]("cache_items", &testCacheItemEncoder[*testCachedItem]{})
   314  	if err != nil {
   315  		b.Fatal(err)
   316  	}
   317  
   318  	db.AddTable(table)
   319  
   320  	b.ResetTimer()
   321  
   322  	b.RunParallel(func(pb *testing.PB) {
   323  		for pb.Next() {
   324  			err = table.Query().
   325  				//Limit(100).
   326  				FindAll(func(tx *kvstore.Tx[*testCachedItem], item kvstore.Item[*testCachedItem]) (goNext bool, err error) {
   327  					return true, nil
   328  				})
   329  			if err != nil {
   330  				b.Fatal(err)
   331  			}
   332  		}
   333  	})
   334  }