From 1e421cb64aca59b22ff4319fea633d97cfedd85a Mon Sep 17 00:00:00 2001 From: Kelvin Mwinuka Date: Fri, 5 Apr 2024 03:11:03 +0800 Subject: [PATCH] Implemented a Clock interface that is injected everywhere time.Now and time.After are used. --- coverage/coverage.out | 1859 +++++++++++++------------- internal/aof/engine.go | 11 + internal/aof/log/store.go | 11 +- internal/aof/preamble/store.go | 12 +- internal/clock/clock.go | 41 + internal/snapshot/snapshot.go | 13 +- pkg/echovault/api_generic_test.go | 90 +- pkg/echovault/echovault.go | 26 +- pkg/echovault/keyspace.go | 4 +- pkg/modules/generic/commands.go | 13 +- pkg/modules/generic/commands_test.go | 131 +- pkg/modules/generic/utils.go | 21 +- pkg/types/types.go | 2 + 13 files changed, 1171 insertions(+), 1063 deletions(-) create mode 100644 internal/clock/clock.go diff --git a/coverage/coverage.out b/coverage/coverage.out index 93efcf6..e9ffc79 100644 --- a/coverage/coverage.out +++ b/coverage/coverage.out @@ -1,223 +1,284 @@ mode: set -github.com/echovault/echovault/pkg/modules/list/commands.go:30.105,32.16 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:32.16,34.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:36.2,38.33 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:38.33,41.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:43.2,43.52 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:43.52,45.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:46.2,48.63 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:48.63,50.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:52.2,52.57 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:55.110,57.16 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:57.16,59.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:61.2,64.9 3 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:64.9,66.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:68.2,68.33 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:68.33,70.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:72.2,72.52 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:72.52,74.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:75.2,78.9 3 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:78.9,80.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:82.2,82.40 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:82.40,84.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:86.2,86.57 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:89.110,91.16 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:91.16,93.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:95.2,99.24 4 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:99.24,101.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:103.2,103.33 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:103.33,105.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:107.2,107.52 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:107.52,109.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:110.2,113.9 3 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:113.9,115.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:118.2,118.40 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:118.40,120.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:123.2,123.51 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:123.51,125.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:127.2,130.15 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:130.15,132.43 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:132.43,135.4 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:136.3,136.20 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:140.2,140.18 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:140.18,142.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:147.2,151.17 4 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:151.17,153.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:155.2,155.13 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:155.13,158.18 3 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:158.18,160.4 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:160.9,162.4 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:165.2,165.19 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:168.108,170.16 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:170.16,172.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:174.2,177.9 3 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:177.9,179.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:181.2,181.33 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:181.33,183.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:185.2,185.51 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:185.51,187.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:188.2,191.9 3 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:191.9,193.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:195.2,195.40 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:195.40,197.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:199.2,200.55 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:200.55,202.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:204.2,204.42 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:207.109,209.16 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:209.16,211.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:213.2,217.24 4 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:217.24,219.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:221.2,221.30 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:221.30,223.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:225.2,225.33 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:225.33,227.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:229.2,229.51 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:229.51,231.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:232.2,235.9 3 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:235.9,237.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:239.2,239.40 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:239.40,241.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:243.2,243.34 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:243.34,244.64 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:244.64,246.4 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:247.3,247.43 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:250.2,250.66 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:250.66,252.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:253.2,253.42 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:256.108,258.16 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:258.16,260.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:262.2,266.9 4 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:266.9,268.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:270.2,272.33 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:272.33,274.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:276.2,276.51 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:276.51,278.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:279.2,282.9 3 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:282.9,284.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:286.2,286.9 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:287.10,287.10 0 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:289.17,291.34 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:291.34,292.26 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:292.26,293.10 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:295.4,295.43 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:295.43,298.5 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:300.17,302.39 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:302.39,303.26 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:303.26,304.10 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:306.4,306.43 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:306.43,309.5 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:313.2,313.61 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:313.61,315.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:317.2,317.55 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:317.55,319.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:321.2,321.42 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:324.109,326.16 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:326.16,328.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:330.2,335.116 5 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:335.116,337.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:339.2,339.75 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:339.75,341.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:343.2,343.54 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:343.54,345.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:346.2,349.16 3 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:349.16,351.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:352.2,357.33 4 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:357.33,359.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:361.2,361.19 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:362.14,364.24 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:364.24,366.4 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:366.9,366.32 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:366.32,368.4 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:369.15,371.24 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:371.24,373.4 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:373.9,373.32 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:373.32,375.4 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:378.2,378.16 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:378.16,380.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:382.2,382.42 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:385.106,387.16 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:387.16,389.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:391.2,393.31 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:393.31,395.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:397.2,399.33 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:399.33,400.34 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:401.17,402.61 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:403.11,404.62 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:404.62,406.5 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:407.4,407.68 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:407.68,409.5 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:411.8,412.52 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:412.52,414.4 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:416.2,421.9 4 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:421.9,423.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:425.2,425.73 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:425.73,427.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:428.2,428.42 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:431.109,433.16 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:433.16,435.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:437.2,441.31 3 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:441.31,443.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:445.2,445.33 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:445.33,446.34 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:447.17,448.61 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:449.11,450.62 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:450.62,452.5 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:453.4,454.68 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:454.68,456.5 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:458.8,459.52 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:459.52,461.4 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:462.3,462.35 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:465.2,469.9 3 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:469.9,471.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:473.2,473.73 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:473.73,475.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:476.2,476.42 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:479.104,481.16 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:481.16,483.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:485.2,487.33 2 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:487.33,489.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:491.2,491.51 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:491.51,493.3 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:494.2,497.9 3 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:497.9,499.3 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:501.2,501.33 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:502.10,503.60 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:503.60,505.4 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:506.3,506.54 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:507.14,508.70 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:508.70,510.4 1 0 -github.com/echovault/echovault/pkg/modules/list/commands.go:511.3,511.64 1 1 -github.com/echovault/echovault/pkg/modules/list/commands.go:515.33,635.2 1 0 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:22.51,23.18 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:23.18,25.3 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:26.2,26.30 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:29.49,30.19 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:30.19,32.3 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:33.2,33.30 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:36.50,37.19 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:37.19,39.3 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:40.2,40.30 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:43.52,44.19 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:44.19,46.3 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:47.2,47.30 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:50.52,51.19 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:51.19,53.3 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:54.2,54.30 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:57.50,58.19 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:58.19,60.3 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:61.2,61.30 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:64.51,65.19 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:65.19,67.3 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:68.2,68.30 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:71.50,72.19 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:72.19,74.3 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:75.2,75.30 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:78.51,79.18 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:79.18,81.3 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:82.2,82.30 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:85.51,86.19 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:86.19,88.3 1 1 -github.com/echovault/echovault/pkg/modules/list/key_funcs.go:89.2,89.38 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:34.108,35.34 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:35.34,37.3 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:38.2,39.9 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:39.9,41.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:42.2,42.67 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:42.67,44.3 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:45.2,45.42 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:48.106,49.19 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:49.19,51.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:53.2,54.9 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:54.9,56.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:58.2,60.30 3 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:60.30,61.27 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:61.27,64.9 3 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:68.2,68.16 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:68.16,70.3 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:73.2,77.18 3 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:77.18,79.3 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:79.8,81.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:82.2,82.21 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:82.21,84.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:85.2,85.17 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:85.17,87.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:89.2,90.29 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:90.29,92.3 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:95.2,96.51 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:96.51,97.22 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:97.22,99.12 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:101.3,101.49 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:103.2,103.51 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:103.51,104.22 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:104.22,106.12 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:108.3,108.49 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:112.2,113.48 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:113.48,114.21 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:114.21,116.12 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:118.3,118.47 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:120.2,120.48 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:120.48,121.21 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:121.21,123.12 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:125.3,125.47 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:129.2,130.79 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:130.79,131.37 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:131.37,133.4 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:135.2,136.30 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:136.30,137.10 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:138.100,140.53 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:141.53,143.52 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:144.52,146.52 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:151.2,153.54 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:153.54,155.3 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:156.2,156.54 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:156.54,158.3 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:160.2,162.25 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:165.102,166.18 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:166.18,168.3 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:170.2,174.35 3 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:174.35,175.36 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:175.36,176.48 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:176.48,178.5 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:179.4,179.12 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:181.3,181.50 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:181.50,182.51 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:182.51,185.5 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:189.2,189.19 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:189.19,192.34 3 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:192.34,195.4 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:196.3,197.28 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:197.28,199.24 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:199.24,201.5 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:203.3,203.26 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:206.2,206.19 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:206.19,208.46 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:208.46,209.43 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:209.43,211.38 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:211.38,213.30 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:213.30,215.7 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:217.5,217.28 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:222.2,222.74 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:225.102,227.9 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:227.9,229.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:230.2,231.33 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:231.33,233.3 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:234.2,235.25 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:238.106,240.9 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:240.9,242.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:243.2,243.45 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:243.45,245.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:246.2,246.42 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:249.108,250.18 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:250.18,252.3 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:253.2,254.9 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:254.9,256.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:257.2,257.53 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:257.53,259.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:260.2,260.42 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:263.106,265.9 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:265.9,267.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:268.2,269.74 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:272.103,273.18 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:273.18,275.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:276.2,277.9 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:277.9,279.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:280.2,282.33 3 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:282.33,285.19 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:285.19,287.4 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:287.9,289.4 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:291.3,291.22 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:291.22,293.4 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:295.3,295.18 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:295.18,297.4 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:299.3,299.43 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:299.43,300.61 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:300.61,302.5 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:303.4,303.58 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:303.58,305.5 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:308.3,308.52 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:308.52,309.23 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:309.23,311.13 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:313.4,313.39 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:316.3,316.52 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:316.52,317.23 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:317.23,319.13 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:321.4,321.39 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:324.3,324.49 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:324.49,325.22 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:325.22,327.13 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:329.4,329.37 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:332.3,332.49 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:332.49,333.22 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:333.22,335.13 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:337.4,337.37 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:340.3,340.45 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:340.45,341.52 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:341.52,343.13 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:345.4,345.41 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:348.3,348.45 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:348.45,349.52 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:349.52,351.5 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:354.3,354.55 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:354.55,356.4 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:358.3,358.55 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:358.55,360.4 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:361.3,361.54 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:364.2,365.25 2 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:368.103,369.19 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:369.19,371.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:373.2,374.9 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:374.9,376.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:378.2,382.16 4 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:382.16,384.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:386.2,386.15 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:386.15,387.35 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:387.35,389.4 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:392.2,396.20 3 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:396.20,397.59 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:397.59,399.4 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:402.2,402.37 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:402.37,403.59 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:403.59,405.4 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:409.2,409.29 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:409.29,413.31 3 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:413.31,414.35 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:414.35,417.43 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:417.43,419.6 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:419.11,422.6 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:423.5,423.10 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:427.3,427.17 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:427.17,429.4 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:432.2,432.42 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:435.103,436.18 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:436.18,438.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:440.2,441.9 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:441.9,443.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:445.2,449.16 4 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:449.16,451.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:453.2,453.15 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:453.15,454.35 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:454.35,456.4 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:459.2,461.20 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:461.20,464.17 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:464.17,466.4 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:467.3,468.17 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:468.17,470.4 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:473.2,473.37 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:473.37,476.17 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:476.17,478.4 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:479.3,480.17 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:480.17,482.4 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:485.2,486.16 2 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:486.16,488.3 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:490.2,490.42 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:493.33,501.60 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:501.60,503.5 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:512.60,514.5 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:523.62,525.7 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:534.62,536.7 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:545.62,547.7 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:556.62,558.7 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:567.62,569.7 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:578.62,580.7 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:589.62,591.7 1 1 +github.com/echovault/echovault/pkg/modules/acl/commands.go:603.62,605.7 1 0 +github.com/echovault/echovault/pkg/modules/acl/commands.go:614.62,616.7 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:29.115,35.29 4 1 +github.com/echovault/echovault/pkg/modules/admin/commands.go:35.29,36.54 1 1 +github.com/echovault/echovault/pkg/modules/admin/commands.go:36.54,42.42 4 1 +github.com/echovault/echovault/pkg/modules/admin/commands.go:42.42,44.5 1 1 +github.com/echovault/echovault/pkg/modules/admin/commands.go:46.4,49.12 3 1 +github.com/echovault/echovault/pkg/modules/admin/commands.go:52.3,52.36 1 1 +github.com/echovault/echovault/pkg/modules/admin/commands.go:52.36,59.43 5 1 +github.com/echovault/echovault/pkg/modules/admin/commands.go:59.43,61.5 1 1 +github.com/echovault/echovault/pkg/modules/admin/commands.go:63.4,65.21 2 1 +github.com/echovault/echovault/pkg/modules/admin/commands.go:69.2,71.25 2 1 +github.com/echovault/echovault/pkg/modules/admin/commands.go:74.109,78.35 3 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:78.35,79.65 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:79.65,80.41 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:80.41,82.5 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:83.4,83.12 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:85.3,85.13 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:88.2,88.51 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:91.110,92.18 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:93.9,98.36 4 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:98.36,99.66 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:99.66,100.52 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:100.52,104.6 3 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:105.5,105.13 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:107.4,108.14 2 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:110.3,111.26 2 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:113.9,117.45 3 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:117.45,119.4 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:120.3,120.42 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:120.42,124.37 3 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:124.37,125.67 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:125.67,126.53 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:126.53,127.59 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:127.59,131.8 3 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:133.6,133.14 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:135.5,135.54 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:135.54,138.6 2 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:140.9,140.50 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:140.50,144.37 3 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:144.37,145.67 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:145.67,146.53 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:146.53,148.24 2 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:148.24,151.8 2 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:153.6,153.14 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:155.5,155.33 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:155.33,158.6 2 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:160.9,160.49 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:160.49,164.37 3 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:164.37,165.67 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:165.67,166.53 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:166.53,167.55 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:167.55,171.8 3 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:173.6,173.14 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:175.5,175.50 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:175.50,178.6 2 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:180.9,182.4 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:183.3,184.26 2 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:185.10,186.54 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:190.103,192.2 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:194.33,202.60 1 1 +github.com/echovault/echovault/pkg/modules/admin/commands.go:202.60,202.86 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:211.60,213.5 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:221.62,221.88 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:230.62,230.88 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:240.62,240.88 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:251.60,253.5 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:254.113,255.49 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:255.49,257.6 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:258.5,258.45 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:267.60,269.5 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:270.113,272.18 2 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:272.18,274.6 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:275.5,275.53 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:284.60,286.5 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:287.113,288.47 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:288.47,290.6 1 0 +github.com/echovault/echovault/pkg/modules/admin/commands.go:291.5,291.45 1 0 github.com/echovault/echovault/pkg/echovault/api_acl.go:125.72,127.23 2 0 github.com/echovault/echovault/pkg/echovault/api_acl.go:127.23,129.3 1 0 github.com/echovault/echovault/pkg/echovault/api_acl.go:130.2,131.16 2 0 @@ -791,139 +852,140 @@ github.com/echovault/echovault/pkg/echovault/cluster.go:87.9,89.3 1 0 github.com/echovault/echovault/pkg/echovault/cluster.go:91.2,91.20 1 0 github.com/echovault/echovault/pkg/echovault/cluster.go:91.20,93.3 1 0 github.com/echovault/echovault/pkg/echovault/cluster.go:95.2,95.24 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:95.66,96.36 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:96.36,98.3 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:104.66,105.36 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:105.36,107.3 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:113.72,114.36 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:114.36,116.3 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:121.78,131.33 2 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:131.33,133.3 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:135.2,146.29 4 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:146.29,155.49 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:155.49,157.44 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:157.44,158.46 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:158.46,160.7 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:162.5,162.17 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:165.3,173.5 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:174.8,184.65 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:184.65,186.44 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:186.44,187.46 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:187.46,189.7 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:191.5,191.17 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:193.72,195.67 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:195.67,197.6 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:198.5,198.68 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:198.68,200.6 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:201.5,202.34 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:206.3,211.60 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:211.60,213.44 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:213.44,214.46 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:214.46,216.7 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:218.5,218.17 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:220.68,222.67 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:222.67,224.6 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:225.5,225.69 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:225.69,227.6 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:228.5,229.34 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:231.51,233.19 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:233.19,235.6 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:241.2,241.61 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:241.61,242.13 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:242.13,243.8 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:243.8,245.83 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:245.83,247.6 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:252.2,252.69 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:252.69,254.3 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:256.2,256.29 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:256.29,260.36 3 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:260.36,262.4 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:265.2,265.30 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:265.30,268.34 2 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:268.34,270.18 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:270.18,272.5 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:276.3,276.71 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:276.71,278.18 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:278.18,280.5 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:284.2,284.23 1 1 -github.com/echovault/echovault/pkg/echovault/echovault.go:287.37,296.16 4 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:296.16,298.3 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:300.2,300.15 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:300.15,303.3 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:305.2,305.27 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:305.27,307.15 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:307.15,309.4 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:309.9,311.4 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:313.3,314.49 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:314.49,316.18 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:316.18,318.5 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:319.4,319.42 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:322.3,325.16 3 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:325.16,327.37 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:327.37,329.19 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:329.19,331.6 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:332.5,333.19 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:333.19,335.6 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:336.5,336.61 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:336.61,338.6 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:342.3,346.5 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:350.2,350.6 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:350.6,352.17 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:352.17,354.12 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:357.3,357.35 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:361.58,363.23 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:363.23,365.3 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:367.2,373.6 4 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:373.6,376.43 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:376.43,379.9 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:382.3,382.17 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:382.17,384.9 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:387.3,389.43 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:389.43,390.9 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:393.3,393.17 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:393.17,394.87 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:394.87,396.5 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:397.4,397.12 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:400.3,403.20 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:403.20,404.12 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:407.3,407.28 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:407.28,409.12 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:413.3,414.7 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:414.7,416.41 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:416.41,418.19 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:418.19,420.6 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:421.5,421.10 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:423.4,424.21 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:424.21,425.10 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:427.4,427.27 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:431.2,431.37 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:431.37,433.3 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:441.34,443.2 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:446.47,447.38 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:447.38,449.3 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:451.2,451.12 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:451.12,452.27 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:452.27,454.53 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:454.53,456.5 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:457.4,457.10 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:460.3,460.62 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:460.62,462.4 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:465.2,465.12 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:468.42,470.2 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:472.43,474.2 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:476.56,478.2 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:481.56,483.2 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:485.44,487.2 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:489.45,491.2 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:494.45,495.40 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:495.40,497.3 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:498.2,498.12 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:498.12,499.55 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:499.55,501.4 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:503.2,503.12 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:508.37,509.26 1 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:509.26,512.3 2 0 -github.com/echovault/echovault/pkg/echovault/echovault.go:515.45,532.2 2 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:99.66,100.36 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:100.36,102.3 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:108.66,109.36 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:109.36,111.3 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:117.72,118.36 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:118.36,120.3 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:125.78,136.33 2 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:136.33,138.3 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:140.2,151.29 4 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:151.29,160.49 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:160.49,162.44 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:162.44,163.46 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:163.46,165.7 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:167.5,167.17 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:170.3,178.5 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:179.8,190.65 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:190.65,192.44 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:192.44,193.46 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:193.46,195.7 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:197.5,197.17 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:199.72,201.67 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:201.67,203.6 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:204.5,204.68 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:204.68,206.6 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:207.5,208.34 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:212.3,218.60 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:218.60,220.44 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:220.44,221.46 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:221.46,223.7 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:225.5,225.17 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:227.68,229.67 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:229.67,231.6 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:232.5,232.69 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:232.69,234.6 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:235.5,236.34 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:238.51,240.19 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:240.19,242.6 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:248.2,248.61 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:248.61,249.13 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:249.13,250.8 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:250.8,252.83 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:252.83,254.6 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:259.2,259.69 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:259.69,261.3 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:263.2,263.29 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:263.29,267.36 3 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:267.36,269.4 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:272.2,272.30 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:272.30,275.34 2 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:275.34,277.18 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:277.18,279.5 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:283.3,283.71 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:283.71,285.18 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:285.18,287.5 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:291.2,291.23 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:294.37,303.16 4 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:303.16,305.3 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:307.2,307.15 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:307.15,310.3 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:312.2,312.27 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:312.27,314.15 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:314.15,316.4 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:316.9,318.4 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:320.3,321.49 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:321.49,323.18 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:323.18,325.5 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:326.4,326.42 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:329.3,332.16 3 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:332.16,334.37 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:334.37,336.19 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:336.19,338.6 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:339.5,340.19 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:340.19,342.6 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:343.5,343.61 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:343.61,345.6 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:349.3,353.5 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:357.2,357.6 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:357.6,359.17 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:359.17,361.12 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:364.3,364.35 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:368.58,370.23 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:370.23,372.3 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:374.2,380.6 4 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:380.6,383.43 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:383.43,386.9 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:389.3,389.17 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:389.17,391.9 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:394.3,396.43 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:396.43,397.9 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:400.3,400.17 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:400.17,401.87 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:401.87,403.5 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:404.4,404.12 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:407.3,410.20 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:410.20,411.12 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:414.3,414.28 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:414.28,416.12 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:420.3,421.7 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:421.7,423.41 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:423.41,425.19 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:425.19,427.6 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:428.5,428.10 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:430.4,431.21 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:431.21,432.10 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:434.4,434.27 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:438.2,438.37 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:438.37,440.3 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:448.34,450.2 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:453.47,454.38 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:454.38,456.3 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:458.2,458.12 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:458.12,459.27 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:459.27,461.53 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:461.53,463.5 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:464.4,464.10 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:467.3,467.62 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:467.62,469.4 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:472.2,472.12 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:476.49,478.2 1 1 +github.com/echovault/echovault/pkg/echovault/echovault.go:480.42,482.2 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:484.43,486.2 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:488.56,490.2 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:493.56,495.2 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:497.44,499.2 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:501.45,503.2 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:506.45,507.40 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:507.40,509.3 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:510.2,510.12 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:510.12,511.55 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:511.55,513.4 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:515.2,515.12 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:520.37,521.26 1 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:521.26,524.3 2 0 +github.com/echovault/echovault/pkg/echovault/echovault.go:527.45,544.2 2 1 github.com/echovault/echovault/pkg/echovault/keyspace.go:37.81,40.34 2 1 github.com/echovault/echovault/pkg/echovault/keyspace.go:40.34,43.3 2 1 github.com/echovault/echovault/pkg/echovault/keyspace.go:45.2,45.6 1 1 @@ -948,8 +1010,8 @@ github.com/echovault/echovault/pkg/echovault/keyspace.go:104.68,105.39 1 1 github.com/echovault/echovault/pkg/echovault/keyspace.go:105.39,107.3 1 1 github.com/echovault/echovault/pkg/echovault/keyspace.go:115.74,117.9 2 1 github.com/echovault/echovault/pkg/echovault/keyspace.go:117.9,119.3 1 1 -github.com/echovault/echovault/pkg/echovault/keyspace.go:121.2,121.74 1 1 -github.com/echovault/echovault/pkg/echovault/keyspace.go:121.74,122.28 1 0 +github.com/echovault/echovault/pkg/echovault/keyspace.go:121.2,121.82 1 1 +github.com/echovault/echovault/pkg/echovault/keyspace.go:121.82,122.28 1 0 github.com/echovault/echovault/pkg/echovault/keyspace.go:122.28,125.18 2 0 github.com/echovault/echovault/pkg/echovault/keyspace.go:125.18,127.5 1 0 github.com/echovault/echovault/pkg/echovault/keyspace.go:128.9,128.64 1 0 @@ -1074,8 +1136,8 @@ github.com/echovault/echovault/pkg/echovault/keyspace.go:541.35,543.10 2 0 github.com/echovault/echovault/pkg/echovault/keyspace.go:547.2,550.25 2 0 github.com/echovault/echovault/pkg/echovault/keyspace.go:550.25,551.52 1 0 github.com/echovault/echovault/pkg/echovault/keyspace.go:551.52,552.12 1 0 -github.com/echovault/echovault/pkg/echovault/keyspace.go:556.3,556.49 1 0 -github.com/echovault/echovault/pkg/echovault/keyspace.go:556.49,558.12 2 0 +github.com/echovault/echovault/pkg/echovault/keyspace.go:556.3,556.57 1 0 +github.com/echovault/echovault/pkg/echovault/keyspace.go:556.57,558.12 2 0 github.com/echovault/echovault/pkg/echovault/keyspace.go:562.3,564.28 3 0 github.com/echovault/echovault/pkg/echovault/keyspace.go:564.28,565.51 1 0 github.com/echovault/echovault/pkg/echovault/keyspace.go:565.51,567.5 1 0 @@ -1122,131 +1184,262 @@ github.com/echovault/echovault/pkg/echovault/modules.go:108.3,108.18 1 0 github.com/echovault/echovault/pkg/echovault/modules.go:112.2,112.34 1 0 github.com/echovault/echovault/pkg/echovault/modules.go:112.34,115.3 2 0 github.com/echovault/echovault/pkg/echovault/modules.go:117.2,117.72 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:36.104,38.16 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:38.16,40.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:42.2,48.16 6 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:48.16,50.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:54.2,54.16 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:54.16,55.34 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:55.34,57.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:57.9,59.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:62.2,62.44 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:62.44,64.34 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:64.34,66.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:67.3,67.36 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:68.8,68.51 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:68.51,70.33 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:70.33,72.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:73.3,73.45 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:74.8,76.34 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:76.34,79.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:79.9,82.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:84.2,84.16 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:84.16,86.3 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:87.2,89.76 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:89.76,91.3 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:94.2,94.28 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:94.28,96.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:98.2,98.17 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:101.105,102.44 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:102.44,104.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:106.2,109.15 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:109.15,110.29 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:110.29,111.16 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:111.16,117.5 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:122.2,122.30 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:122.30,123.15 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:123.15,128.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:133.2,133.28 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:133.28,134.31 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:134.31,135.52 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:135.52,137.5 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:138.4,139.12 2 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:141.3,141.60 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:141.60,143.4 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:144.3,144.55 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:148.2,148.28 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:148.28,149.58 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:149.58,151.4 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:154.2,154.42 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:157.104,159.16 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:159.16,161.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:162.2,164.33 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:164.33,166.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:168.2,169.16 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:169.16,171.3 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:172.2,176.51 3 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:179.105,181.16 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:181.16,183.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:185.2,188.27 3 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:188.27,189.31 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:189.31,191.12 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:193.3,193.33 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:193.33,195.18 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:195.18,197.5 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:198.4,199.12 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:201.3,201.19 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:203.2,203.15 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:203.15,204.34 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:204.34,205.14 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:205.14,208.5 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:212.2,212.28 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:212.28,214.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:216.2,218.30 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:218.30,219.24 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:219.24,221.12 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:223.3,223.96 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:226.2,226.19 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:229.104,231.16 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:231.16,233.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:234.2,235.27 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:235.27,237.17 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:237.17,239.12 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:241.3,241.13 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:243.2,243.51 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:246.108,248.16 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:248.16,250.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:252.2,254.33 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:254.33,256.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:258.2,258.51 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:258.51,260.3 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:261.2,264.31 3 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:264.31,266.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:268.2,270.30 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:273.111,275.16 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:275.16,277.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:279.2,281.33 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:281.33,283.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:285.2,285.52 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:285.52,287.3 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:288.2,292.31 3 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:292.31,294.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:296.2,297.46 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:297.46,299.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:301.2,301.47 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:304.104,306.16 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:306.16,308.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:310.2,314.33 3 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:314.33,316.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:318.2,318.52 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:318.52,320.3 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:321.2,325.31 3 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:325.31,327.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:329.2,330.39 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:330.39,332.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:334.2,334.12 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:334.12,336.3 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:338.2,338.47 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:341.107,343.16 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:343.16,345.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:347.2,351.16 3 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:351.16,353.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:354.2,355.42 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:355.42,357.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:359.2,359.33 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:359.33,361.3 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:363.2,363.51 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:363.51,365.3 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:366.2,368.19 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:368.19,371.3 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:373.2,375.33 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:376.12,377.39 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:377.39,379.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:380.3,380.46 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:381.12,382.39 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:382.39,384.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:385.3,385.46 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:386.12,387.39 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:387.39,389.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:390.3,390.39 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:390.39,392.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:393.3,393.46 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:394.12,395.39 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:395.39,396.40 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:396.40,398.5 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:399.4,399.47 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:401.3,401.46 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:402.10,403.71 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:406.2,406.30 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:409.109,411.16 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:411.16,413.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:415.2,419.16 3 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:419.16,421.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:422.2,423.44 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:423.44,425.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:427.2,427.33 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:427.33,429.3 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:431.2,431.51 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:431.51,433.3 1 0 +github.com/echovault/echovault/pkg/modules/generic/commands.go:434.2,436.19 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:436.19,439.3 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:441.2,443.33 2 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:444.12,445.39 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:445.39,447.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:448.3,448.46 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:449.12,450.39 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:450.39,452.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:453.3,453.46 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:454.12,455.39 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:455.39,457.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:458.3,458.39 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:458.39,460.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:461.3,461.46 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:462.12,463.39 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:463.39,464.40 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:464.40,466.5 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:467.4,467.47 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:469.3,469.46 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:470.10,471.71 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:474.2,474.30 1 1 +github.com/echovault/echovault/pkg/modules/generic/commands.go:477.33,646.2 1 0 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:22.49,23.34 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:23.34,25.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:26.2,26.30 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:29.50,30.25 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:30.25,32.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:33.2,34.30 2 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:34.30,35.15 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:35.15,37.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:39.2,39.18 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:42.49,43.19 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:43.19,45.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:46.2,46.30 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:49.50,50.18 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:50.18,52.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:53.2,53.21 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:56.49,57.18 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:57.18,59.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:60.2,60.21 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:63.53,64.19 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:64.19,66.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:67.2,67.21 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:70.56,71.19 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:71.19,73.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:74.2,74.21 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:77.49,78.19 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:78.19,80.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:81.2,81.21 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:84.52,85.34 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:85.34,87.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:88.2,88.30 1 1 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:91.54,92.34 1 0 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:92.34,94.3 1 0 +github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:95.2,95.30 1 0 +github.com/echovault/echovault/pkg/modules/generic/utils.go:32.96,33.19 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:33.19,35.3 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:36.2,36.33 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:37.13,39.53 2 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:41.12,42.26 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:42.26,44.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:45.3,46.53 2 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:48.12,49.26 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:49.26,51.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:52.3,53.53 2 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:55.12,56.19 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:56.19,58.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:59.3,59.29 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:59.29,61.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:62.3,64.17 3 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:64.17,66.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:67.3,68.53 2 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:70.12,71.19 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:71.19,73.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:74.3,74.29 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:74.29,76.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:77.3,79.17 3 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:79.17,81.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:82.3,83.53 2 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:85.14,86.19 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:86.19,88.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:89.3,89.29 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:89.29,91.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:92.3,94.17 3 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:94.17,96.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:97.3,98.53 2 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:100.14,101.19 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:101.19,103.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:104.3,104.29 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:104.29,106.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:107.3,109.17 3 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:109.17,111.4 1 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:112.3,113.53 2 1 +github.com/echovault/echovault/pkg/modules/generic/utils.go:115.10,116.95 1 1 github.com/echovault/echovault/pkg/modules/connection/commands.go:26.108,27.18 1 1 github.com/echovault/echovault/pkg/modules/connection/commands.go:28.10,29.54 1 1 github.com/echovault/echovault/pkg/modules/connection/commands.go:30.9,31.34 1 1 github.com/echovault/echovault/pkg/modules/connection/commands.go:32.9,33.72 1 1 github.com/echovault/echovault/pkg/modules/connection/commands.go:37.33,45.60 1 0 github.com/echovault/echovault/pkg/modules/connection/commands.go:45.60,47.5 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:29.115,35.29 4 1 -github.com/echovault/echovault/pkg/modules/admin/commands.go:35.29,36.54 1 1 -github.com/echovault/echovault/pkg/modules/admin/commands.go:36.54,42.42 4 1 -github.com/echovault/echovault/pkg/modules/admin/commands.go:42.42,44.5 1 1 -github.com/echovault/echovault/pkg/modules/admin/commands.go:46.4,49.12 3 1 -github.com/echovault/echovault/pkg/modules/admin/commands.go:52.3,52.36 1 1 -github.com/echovault/echovault/pkg/modules/admin/commands.go:52.36,59.43 5 1 -github.com/echovault/echovault/pkg/modules/admin/commands.go:59.43,61.5 1 1 -github.com/echovault/echovault/pkg/modules/admin/commands.go:63.4,65.21 2 1 -github.com/echovault/echovault/pkg/modules/admin/commands.go:69.2,71.25 2 1 -github.com/echovault/echovault/pkg/modules/admin/commands.go:74.109,78.35 3 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:78.35,79.65 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:79.65,80.41 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:80.41,82.5 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:83.4,83.12 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:85.3,85.13 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:88.2,88.51 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:91.110,92.18 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:93.9,98.36 4 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:98.36,99.66 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:99.66,100.52 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:100.52,104.6 3 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:105.5,105.13 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:107.4,108.14 2 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:110.3,111.26 2 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:113.9,117.45 3 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:117.45,119.4 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:120.3,120.42 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:120.42,124.37 3 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:124.37,125.67 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:125.67,126.53 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:126.53,127.59 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:127.59,131.8 3 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:133.6,133.14 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:135.5,135.54 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:135.54,138.6 2 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:140.9,140.50 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:140.50,144.37 3 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:144.37,145.67 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:145.67,146.53 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:146.53,148.24 2 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:148.24,151.8 2 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:153.6,153.14 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:155.5,155.33 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:155.33,158.6 2 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:160.9,160.49 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:160.49,164.37 3 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:164.37,165.67 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:165.67,166.53 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:166.53,167.55 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:167.55,171.8 3 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:173.6,173.14 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:175.5,175.50 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:175.50,178.6 2 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:180.9,182.4 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:183.3,184.26 2 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:185.10,186.54 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:190.103,192.2 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:194.33,202.60 1 1 -github.com/echovault/echovault/pkg/modules/admin/commands.go:202.60,202.86 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:211.60,213.5 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:221.62,221.88 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:230.62,230.88 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:240.62,240.88 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:251.60,253.5 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:254.113,255.49 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:255.49,257.6 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:258.5,258.45 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:267.60,269.5 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:270.113,272.18 2 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:272.18,274.6 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:275.5,275.53 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:284.60,286.5 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:287.113,288.47 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:288.47,290.6 1 0 -github.com/echovault/echovault/pkg/modules/admin/commands.go:291.5,291.45 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:28.113,30.9 2 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:30.9,32.3 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:34.2,36.24 2 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:36.24,38.3 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:40.2,43.17 3 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:46.115,48.9 2 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:48.9,50.3 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:52.2,56.66 3 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:59.108,61.9 2 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:61.9,63.3 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:64.2,64.19 1 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:64.19,66.3 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:67.2,68.42 2 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:71.113,72.18 1 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:72.18,74.3 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:76.2,77.9 2 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:77.9,79.3 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:81.2,82.19 2 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:82.19,84.3 1 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:86.2,86.38 1 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:89.109,91.9 2 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:91.9,93.3 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:94.2,95.49 2 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:98.112,100.9 2 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:100.9,102.3 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:103.2,103.36 1 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:106.33,114.60 1 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:114.60,116.21 1 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:116.21,118.6 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:119.5,119.24 1 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:129.60,131.21 1 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:131.21,133.6 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:134.5,134.24 1 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:144.60,146.22 1 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:146.22,148.6 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:149.5,149.33 1 1 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:161.60,164.5 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:175.60,178.5 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:187.60,187.86 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:188.101,190.5 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:200.62,200.88 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:209.62,209.88 1 0 -github.com/echovault/echovault/pkg/modules/pubsub/commands.go:219.62,219.85 1 0 github.com/echovault/echovault/pkg/modules/hash/commands.go:31.105,33.16 2 1 github.com/echovault/echovault/pkg/modules/hash/commands.go:33.16,35.3 1 1 github.com/echovault/echovault/pkg/modules/hash/commands.go:37.2,40.25 3 1 @@ -1511,460 +1704,268 @@ github.com/echovault/echovault/pkg/modules/hash/key_funcs.go:99.2,99.22 1 1 github.com/echovault/echovault/pkg/modules/hash/key_funcs.go:102.50,103.18 1 1 github.com/echovault/echovault/pkg/modules/hash/key_funcs.go:103.18,105.3 1 1 github.com/echovault/echovault/pkg/modules/hash/key_funcs.go:106.2,106.22 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:34.108,35.34 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:35.34,37.3 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:38.2,39.9 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:39.9,41.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:42.2,42.67 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:42.67,44.3 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:45.2,45.42 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:48.106,49.19 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:49.19,51.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:53.2,54.9 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:54.9,56.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:58.2,60.30 3 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:60.30,61.27 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:61.27,64.9 3 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:68.2,68.16 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:68.16,70.3 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:73.2,77.18 3 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:77.18,79.3 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:79.8,81.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:82.2,82.21 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:82.21,84.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:85.2,85.17 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:85.17,87.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:89.2,90.29 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:90.29,92.3 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:95.2,96.51 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:96.51,97.22 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:97.22,99.12 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:101.3,101.49 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:103.2,103.51 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:103.51,104.22 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:104.22,106.12 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:108.3,108.49 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:112.2,113.48 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:113.48,114.21 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:114.21,116.12 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:118.3,118.47 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:120.2,120.48 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:120.48,121.21 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:121.21,123.12 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:125.3,125.47 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:129.2,130.79 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:130.79,131.37 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:131.37,133.4 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:135.2,136.30 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:136.30,137.10 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:138.100,140.53 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:141.53,143.52 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:144.52,146.52 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:151.2,153.54 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:153.54,155.3 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:156.2,156.54 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:156.54,158.3 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:160.2,162.25 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:165.102,166.18 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:166.18,168.3 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:170.2,174.35 3 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:174.35,175.36 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:175.36,176.48 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:176.48,178.5 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:179.4,179.12 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:181.3,181.50 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:181.50,182.51 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:182.51,185.5 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:189.2,189.19 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:189.19,192.34 3 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:192.34,195.4 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:196.3,197.28 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:197.28,199.24 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:199.24,201.5 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:203.3,203.26 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:206.2,206.19 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:206.19,208.46 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:208.46,209.43 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:209.43,211.38 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:211.38,213.30 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:213.30,215.7 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:217.5,217.28 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:222.2,222.74 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:225.102,227.9 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:227.9,229.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:230.2,231.33 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:231.33,233.3 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:234.2,235.25 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:238.106,240.9 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:240.9,242.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:243.2,243.45 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:243.45,245.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:246.2,246.42 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:249.108,250.18 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:250.18,252.3 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:253.2,254.9 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:254.9,256.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:257.2,257.53 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:257.53,259.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:260.2,260.42 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:263.106,265.9 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:265.9,267.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:268.2,269.74 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:272.103,273.18 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:273.18,275.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:276.2,277.9 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:277.9,279.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:280.2,282.33 3 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:282.33,285.19 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:285.19,287.4 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:287.9,289.4 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:291.3,291.22 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:291.22,293.4 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:295.3,295.18 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:295.18,297.4 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:299.3,299.43 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:299.43,300.61 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:300.61,302.5 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:303.4,303.58 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:303.58,305.5 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:308.3,308.52 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:308.52,309.23 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:309.23,311.13 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:313.4,313.39 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:316.3,316.52 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:316.52,317.23 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:317.23,319.13 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:321.4,321.39 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:324.3,324.49 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:324.49,325.22 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:325.22,327.13 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:329.4,329.37 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:332.3,332.49 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:332.49,333.22 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:333.22,335.13 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:337.4,337.37 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:340.3,340.45 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:340.45,341.52 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:341.52,343.13 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:345.4,345.41 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:348.3,348.45 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:348.45,349.52 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:349.52,351.5 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:354.3,354.55 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:354.55,356.4 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:358.3,358.55 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:358.55,360.4 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:361.3,361.54 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:364.2,365.25 2 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:368.103,369.19 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:369.19,371.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:373.2,374.9 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:374.9,376.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:378.2,382.16 4 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:382.16,384.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:386.2,386.15 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:386.15,387.35 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:387.35,389.4 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:392.2,396.20 3 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:396.20,397.59 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:397.59,399.4 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:402.2,402.37 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:402.37,403.59 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:403.59,405.4 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:409.2,409.29 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:409.29,413.31 3 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:413.31,414.35 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:414.35,417.43 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:417.43,419.6 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:419.11,422.6 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:423.5,423.10 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:427.3,427.17 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:427.17,429.4 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:432.2,432.42 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:435.103,436.18 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:436.18,438.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:440.2,441.9 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:441.9,443.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:445.2,449.16 4 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:449.16,451.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:453.2,453.15 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:453.15,454.35 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:454.35,456.4 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:459.2,461.20 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:461.20,464.17 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:464.17,466.4 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:467.3,468.17 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:468.17,470.4 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:473.2,473.37 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:473.37,476.17 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:476.17,478.4 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:479.3,480.17 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:480.17,482.4 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:485.2,486.16 2 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:486.16,488.3 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:490.2,490.42 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:493.33,501.60 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:501.60,503.5 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:512.60,514.5 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:523.62,525.7 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:534.62,536.7 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:545.62,547.7 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:556.62,558.7 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:567.62,569.7 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:578.62,580.7 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:589.62,591.7 1 1 -github.com/echovault/echovault/pkg/modules/acl/commands.go:603.62,605.7 1 0 -github.com/echovault/echovault/pkg/modules/acl/commands.go:614.62,616.7 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:36.104,38.16 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:38.16,40.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:42.2,47.16 5 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:47.16,49.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:53.2,53.16 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:53.16,54.34 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:54.34,56.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:56.9,58.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:61.2,61.44 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:61.44,63.34 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:63.34,65.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:66.3,66.36 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:67.8,67.51 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:67.51,69.33 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:69.33,71.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:72.3,72.45 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:73.8,75.34 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:75.34,78.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:78.9,81.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:83.2,83.16 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:83.16,85.3 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:86.2,88.76 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:88.76,90.3 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:93.2,93.28 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:93.28,95.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:97.2,97.17 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:100.105,101.44 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:101.44,103.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:105.2,108.15 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:108.15,109.29 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:109.29,110.16 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:110.16,116.5 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:121.2,121.30 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:121.30,122.15 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:122.15,127.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:132.2,132.28 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:132.28,133.31 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:133.31,134.52 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:134.52,136.5 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:137.4,138.12 2 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:140.3,140.60 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:140.60,142.4 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:143.3,143.55 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:147.2,147.28 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:147.28,148.58 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:148.58,150.4 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:153.2,153.42 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:156.104,158.16 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:158.16,160.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:161.2,163.33 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:163.33,165.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:167.2,168.16 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:168.16,170.3 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:171.2,175.51 3 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:178.105,180.16 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:180.16,182.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:184.2,187.27 3 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:187.27,188.31 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:188.31,190.12 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:192.3,192.33 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:192.33,194.18 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:194.18,196.5 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:197.4,198.12 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:200.3,200.19 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:202.2,202.15 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:202.15,203.34 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:203.34,204.14 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:204.14,207.5 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:211.2,211.28 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:211.28,213.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:215.2,217.30 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:217.30,218.24 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:218.24,220.12 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:222.3,222.96 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:225.2,225.19 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:228.104,230.16 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:230.16,232.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:233.2,234.27 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:234.27,236.17 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:236.17,238.12 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:240.3,240.13 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:242.2,242.51 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:245.108,247.16 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:247.16,249.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:251.2,253.33 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:253.33,255.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:257.2,257.51 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:257.51,259.3 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:260.2,263.31 3 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:263.31,265.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:267.2,269.30 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:272.111,274.16 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:274.16,276.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:278.2,280.33 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:280.33,282.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:284.2,284.52 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:284.52,286.3 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:287.2,291.31 3 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:291.31,293.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:295.2,296.46 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:296.46,298.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:300.2,300.47 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:303.104,305.16 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:305.16,307.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:309.2,311.33 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:311.33,313.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:315.2,315.52 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:315.52,317.3 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:318.2,322.31 3 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:322.31,324.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:326.2,327.39 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:327.39,329.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:331.2,331.12 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:331.12,333.3 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:335.2,335.47 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:338.107,340.16 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:340.16,342.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:344.2,348.16 3 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:348.16,350.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:351.2,352.42 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:352.42,354.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:356.2,356.33 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:356.33,358.3 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:360.2,360.51 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:360.51,362.3 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:363.2,365.19 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:365.19,368.3 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:370.2,372.33 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:373.12,374.39 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:374.39,376.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:377.3,377.46 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:378.12,379.39 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:379.39,381.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:382.3,382.46 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:383.12,384.39 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:384.39,386.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:387.3,387.39 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:387.39,389.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:390.3,390.46 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:391.12,392.39 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:392.39,393.40 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:393.40,395.5 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:396.4,396.47 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:398.3,398.46 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:399.10,400.71 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:403.2,403.30 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:406.109,408.16 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:408.16,410.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:412.2,416.16 3 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:416.16,418.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:419.2,420.44 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:420.44,422.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:424.2,424.33 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:424.33,426.3 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:428.2,428.51 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:428.51,430.3 1 0 -github.com/echovault/echovault/pkg/modules/generic/commands.go:431.2,433.19 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:433.19,436.3 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:438.2,440.33 2 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:441.12,442.39 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:442.39,444.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:445.3,445.46 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:446.12,447.39 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:447.39,449.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:450.3,450.46 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:451.12,452.39 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:452.39,454.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:455.3,455.39 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:455.39,457.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:458.3,458.46 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:459.12,460.39 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:460.39,461.40 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:461.40,463.5 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:464.4,464.47 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:466.3,466.46 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:467.10,468.71 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:471.2,471.30 1 1 -github.com/echovault/echovault/pkg/modules/generic/commands.go:474.33,643.2 1 0 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:22.49,23.34 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:23.34,25.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:26.2,26.30 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:29.50,30.25 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:30.25,32.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:33.2,34.30 2 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:34.30,35.15 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:35.15,37.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:39.2,39.18 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:42.49,43.19 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:43.19,45.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:46.2,46.30 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:49.50,50.18 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:50.18,52.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:53.2,53.21 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:56.49,57.18 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:57.18,59.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:60.2,60.21 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:63.53,64.19 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:64.19,66.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:67.2,67.21 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:70.56,71.19 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:71.19,73.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:74.2,74.21 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:77.49,78.19 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:78.19,80.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:81.2,81.21 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:84.52,85.34 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:85.34,87.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:88.2,88.30 1 1 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:91.54,92.34 1 0 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:92.34,94.3 1 0 -github.com/echovault/echovault/pkg/modules/generic/key_funcs.go:95.2,95.30 1 0 -github.com/echovault/echovault/pkg/modules/generic/utils.go:31.77,32.19 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:32.19,34.3 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:35.2,35.33 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:36.13,38.46 2 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:40.12,41.26 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:41.26,43.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:44.3,45.46 2 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:47.12,48.26 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:48.26,50.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:51.3,52.46 2 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:54.12,55.19 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:55.19,57.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:58.3,58.29 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:58.29,60.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:61.3,63.17 3 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:63.17,65.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:66.3,67.46 2 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:69.12,70.19 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:70.19,72.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:73.3,73.29 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:73.29,75.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:76.3,78.17 3 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:78.17,80.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:81.3,82.46 2 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:84.14,85.19 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:85.19,87.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:88.3,88.29 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:88.29,90.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:91.3,93.17 3 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:93.17,95.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:96.3,97.46 2 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:99.14,100.19 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:100.19,102.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:103.3,103.29 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:103.29,105.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:106.3,108.17 3 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:108.17,110.4 1 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:111.3,112.46 2 1 -github.com/echovault/echovault/pkg/modules/generic/utils.go:114.10,115.95 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:30.105,32.16 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:32.16,34.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:36.2,38.33 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:38.33,41.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:43.2,43.52 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:43.52,45.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:46.2,48.63 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:48.63,50.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:52.2,52.57 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:55.110,57.16 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:57.16,59.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:61.2,64.9 3 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:64.9,66.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:68.2,68.33 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:68.33,70.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:72.2,72.52 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:72.52,74.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:75.2,78.9 3 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:78.9,80.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:82.2,82.40 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:82.40,84.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:86.2,86.57 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:89.110,91.16 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:91.16,93.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:95.2,99.24 4 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:99.24,101.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:103.2,103.33 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:103.33,105.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:107.2,107.52 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:107.52,109.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:110.2,113.9 3 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:113.9,115.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:118.2,118.40 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:118.40,120.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:123.2,123.51 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:123.51,125.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:127.2,130.15 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:130.15,132.43 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:132.43,135.4 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:136.3,136.20 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:140.2,140.18 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:140.18,142.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:147.2,151.17 4 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:151.17,153.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:155.2,155.13 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:155.13,158.18 3 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:158.18,160.4 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:160.9,162.4 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:165.2,165.19 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:168.108,170.16 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:170.16,172.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:174.2,177.9 3 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:177.9,179.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:181.2,181.33 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:181.33,183.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:185.2,185.51 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:185.51,187.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:188.2,191.9 3 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:191.9,193.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:195.2,195.40 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:195.40,197.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:199.2,200.55 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:200.55,202.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:204.2,204.42 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:207.109,209.16 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:209.16,211.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:213.2,217.24 4 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:217.24,219.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:221.2,221.30 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:221.30,223.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:225.2,225.33 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:225.33,227.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:229.2,229.51 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:229.51,231.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:232.2,235.9 3 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:235.9,237.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:239.2,239.40 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:239.40,241.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:243.2,243.34 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:243.34,244.64 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:244.64,246.4 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:247.3,247.43 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:250.2,250.66 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:250.66,252.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:253.2,253.42 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:256.108,258.16 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:258.16,260.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:262.2,266.9 4 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:266.9,268.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:270.2,272.33 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:272.33,274.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:276.2,276.51 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:276.51,278.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:279.2,282.9 3 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:282.9,284.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:286.2,286.9 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:287.10,287.10 0 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:289.17,291.34 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:291.34,292.26 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:292.26,293.10 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:295.4,295.43 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:295.43,298.5 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:300.17,302.39 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:302.39,303.26 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:303.26,304.10 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:306.4,306.43 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:306.43,309.5 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:313.2,313.61 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:313.61,315.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:317.2,317.55 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:317.55,319.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:321.2,321.42 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:324.109,326.16 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:326.16,328.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:330.2,335.116 5 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:335.116,337.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:339.2,339.75 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:339.75,341.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:343.2,343.54 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:343.54,345.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:346.2,349.16 3 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:349.16,351.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:352.2,357.33 4 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:357.33,359.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:361.2,361.19 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:362.14,364.24 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:364.24,366.4 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:366.9,366.32 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:366.32,368.4 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:369.15,371.24 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:371.24,373.4 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:373.9,373.32 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:373.32,375.4 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:378.2,378.16 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:378.16,380.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:382.2,382.42 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:385.106,387.16 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:387.16,389.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:391.2,393.31 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:393.31,395.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:397.2,399.33 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:399.33,400.34 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:401.17,402.61 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:403.11,404.62 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:404.62,406.5 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:407.4,407.68 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:407.68,409.5 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:411.8,412.52 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:412.52,414.4 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:416.2,421.9 4 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:421.9,423.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:425.2,425.73 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:425.73,427.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:428.2,428.42 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:431.109,433.16 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:433.16,435.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:437.2,441.31 3 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:441.31,443.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:445.2,445.33 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:445.33,446.34 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:447.17,448.61 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:449.11,450.62 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:450.62,452.5 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:453.4,454.68 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:454.68,456.5 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:458.8,459.52 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:459.52,461.4 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:462.3,462.35 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:465.2,469.9 3 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:469.9,471.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:473.2,473.73 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:473.73,475.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:476.2,476.42 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:479.104,481.16 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:481.16,483.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:485.2,487.33 2 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:487.33,489.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:491.2,491.51 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:491.51,493.3 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:494.2,497.9 3 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:497.9,499.3 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:501.2,501.33 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:502.10,503.60 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:503.60,505.4 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:506.3,506.54 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:507.14,508.70 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:508.70,510.4 1 0 +github.com/echovault/echovault/pkg/modules/list/commands.go:511.3,511.64 1 1 +github.com/echovault/echovault/pkg/modules/list/commands.go:515.33,635.2 1 0 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:22.51,23.18 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:23.18,25.3 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:26.2,26.30 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:29.49,30.19 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:30.19,32.3 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:33.2,33.30 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:36.50,37.19 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:37.19,39.3 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:40.2,40.30 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:43.52,44.19 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:44.19,46.3 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:47.2,47.30 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:50.52,51.19 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:51.19,53.3 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:54.2,54.30 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:57.50,58.19 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:58.19,60.3 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:61.2,61.30 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:64.51,65.19 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:65.19,67.3 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:68.2,68.30 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:71.50,72.19 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:72.19,74.3 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:75.2,75.30 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:78.51,79.18 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:79.18,81.3 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:82.2,82.30 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:85.51,86.19 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:86.19,88.3 1 1 +github.com/echovault/echovault/pkg/modules/list/key_funcs.go:89.2,89.38 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:28.113,30.9 2 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:30.9,32.3 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:34.2,36.24 2 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:36.24,38.3 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:40.2,43.17 3 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:46.115,48.9 2 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:48.9,50.3 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:52.2,56.66 3 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:59.108,61.9 2 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:61.9,63.3 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:64.2,64.19 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:64.19,66.3 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:67.2,68.42 2 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:71.113,72.18 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:72.18,74.3 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:76.2,77.9 2 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:77.9,79.3 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:81.2,82.19 2 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:82.19,84.3 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:86.2,86.38 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:89.109,91.9 2 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:91.9,93.3 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:94.2,95.49 2 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:98.112,100.9 2 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:100.9,102.3 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:103.2,103.36 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:106.33,114.60 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:114.60,116.21 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:116.21,118.6 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:119.5,119.24 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:129.60,131.21 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:131.21,133.6 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:134.5,134.24 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:144.60,146.22 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:146.22,148.6 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:149.5,149.33 1 1 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:161.60,164.5 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:175.60,178.5 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:187.60,187.86 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:188.101,190.5 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:200.62,200.88 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:209.62,209.88 1 0 +github.com/echovault/echovault/pkg/modules/pubsub/commands.go:219.62,219.85 1 0 github.com/echovault/echovault/pkg/modules/set/commands.go:30.108,32.16 2 1 github.com/echovault/echovault/pkg/modules/set/commands.go:32.16,34.3 1 1 github.com/echovault/echovault/pkg/modules/set/commands.go:36.2,40.33 3 1 diff --git a/internal/aof/engine.go b/internal/aof/engine.go index 7922c80..e630c16 100644 --- a/internal/aof/engine.go +++ b/internal/aof/engine.go @@ -19,6 +19,7 @@ import ( "github.com/echovault/echovault/internal" logstore "github.com/echovault/echovault/internal/aof/log" "github.com/echovault/echovault/internal/aof/preamble" + "github.com/echovault/echovault/internal/clock" "log" "sync" ) @@ -27,6 +28,7 @@ import ( // Logging in replication clusters is handled in the raft layer. type Engine struct { + clock clock.Clock syncStrategy string directory string preambleRW preamble.PreambleReadWriter @@ -45,6 +47,12 @@ type Engine struct { handleCommand func(command []byte) } +func WithClock(clock clock.Clock) func(engine *Engine) { + return func(engine *Engine) { + engine.clock = clock + } +} + func WithStrategy(strategy string) func(engine *Engine) { return func(engine *Engine) { engine.syncStrategy = strategy @@ -101,6 +109,7 @@ func WithAppendReadWriter(rw logstore.AppendReadWriter) func(engine *Engine) { func NewAOFEngine(options ...func(engine *Engine)) *Engine { engine := &Engine{ + clock: clock.NewClock(), syncStrategy: "everysec", directory: "", mut: sync.Mutex{}, @@ -121,6 +130,7 @@ func NewAOFEngine(options ...func(engine *Engine)) *Engine { // Setup Preamble engine engine.preambleStore = preamble.NewPreambleStore( + preamble.WithClock(engine.clock), preamble.WithDirectory(engine.directory), preamble.WithReadWriter(engine.preambleRW), preamble.WithGetStateFunc(engine.getStateFunc), @@ -129,6 +139,7 @@ func NewAOFEngine(options ...func(engine *Engine)) *Engine { // Setup AOF log store engine engine.appendStore = logstore.NewAppendStore( + logstore.WithClock(engine.clock), logstore.WithDirectory(engine.directory), logstore.WithStrategy(engine.syncStrategy), logstore.WithReadWriter(engine.appendRW), diff --git a/internal/aof/log/store.go b/internal/aof/log/store.go index 2720ac3..18f2e70 100644 --- a/internal/aof/log/store.go +++ b/internal/aof/log/store.go @@ -19,6 +19,7 @@ import ( "bytes" "errors" "fmt" + "github.com/echovault/echovault/internal/clock" "io" "log" "os" @@ -36,6 +37,7 @@ type AppendReadWriter interface { } type AppendStore struct { + clock clock.Clock strategy string // Append file sync strategy. Can only be "always", "everysec", or "no mut sync.Mutex // Store mutex rw AppendReadWriter // The ReadWriter used to persist and load the log @@ -43,6 +45,12 @@ type AppendStore struct { handleCommand func(command []byte) // Function to handle command read from AOF log after restore } +func WithClock(clock clock.Clock) func(store *AppendStore) { + return func(store *AppendStore) { + store.clock = clock + } +} + func WithStrategy(strategy string) func(store *AppendStore) { return func(store *AppendStore) { store.strategy = strategy @@ -69,6 +77,7 @@ func WithHandleCommandFunc(f func(command []byte)) func(store *AppendStore) { func NewAppendStore(options ...func(store *AppendStore)) *AppendStore { store := &AppendStore{ + clock: clock.NewClock(), directory: "", strategy: "everysec", rw: nil, @@ -103,7 +112,7 @@ func NewAppendStore(options ...func(store *AppendStore)) *AppendStore { log.Println(fmt.Errorf("new append store error: %+v", err)) break } - <-time.After(1 * time.Second) + <-store.clock.After(1 * time.Second) } }() } diff --git a/internal/aof/preamble/store.go b/internal/aof/preamble/store.go index 19aae77..4d51dd2 100644 --- a/internal/aof/preamble/store.go +++ b/internal/aof/preamble/store.go @@ -18,12 +18,12 @@ import ( "encoding/json" "fmt" "github.com/echovault/echovault/internal" + "github.com/echovault/echovault/internal/clock" "io" "log" "os" "path" "sync" - "time" ) type PreambleReadWriter interface { @@ -34,6 +34,7 @@ type PreambleReadWriter interface { } type PreambleStore struct { + clock clock.Clock rw PreambleReadWriter mut sync.Mutex directory string @@ -41,6 +42,12 @@ type PreambleStore struct { setKeyDataFunc func(key string, data internal.KeyData) } +func WithClock(clock clock.Clock) func(store *PreambleStore) { + return func(store *PreambleStore) { + store.clock = clock + } +} + func WithReadWriter(rw PreambleReadWriter) func(store *PreambleStore) { return func(store *PreambleStore) { store.rw = rw @@ -67,6 +74,7 @@ func WithDirectory(directory string) func(store *PreambleStore) { func NewPreambleStore(options ...func(store *PreambleStore)) *PreambleStore { store := &PreambleStore{ + clock: clock.NewClock(), rw: nil, mut: sync.Mutex{}, directory: "", @@ -166,7 +174,7 @@ func (store *PreambleStore) Close() error { func (store *PreambleStore) filterExpiredKeys(state map[string]internal.KeyData) map[string]internal.KeyData { var keysToDelete []string for k, v := range state { - if v.ExpireAt.Before(time.Now()) { + if v.ExpireAt.Before(store.clock.Now()) { keysToDelete = append(keysToDelete, k) } } diff --git a/internal/clock/clock.go b/internal/clock/clock.go new file mode 100644 index 0000000..036a06a --- /dev/null +++ b/internal/clock/clock.go @@ -0,0 +1,41 @@ +package clock + +import ( + "os" + "strings" + "time" +) + +type Clock interface { + Now() time.Time + After(d time.Duration) <-chan time.Time +} + +func NewClock() Clock { + // If we're in a test environment, return the mock clock. + if strings.Contains(os.Args[0], ".test") { + return MockClock{} + } + return RealClock{} +} + +type RealClock struct{} + +func (RealClock) Now() time.Time { + return time.Now() +} + +func (RealClock) After(d time.Duration) <-chan time.Time { + return time.After(d) +} + +type MockClock struct{} + +func (MockClock) Now() time.Time { + t, _ := time.Parse(time.RFC3339, "2036-01-02T15:04:05+07:00") + return t +} + +func (MockClock) After(d time.Duration) <-chan time.Time { + return time.After(d) +} diff --git a/internal/snapshot/snapshot.go b/internal/snapshot/snapshot.go index 4ce4a7b..2a7f455 100644 --- a/internal/snapshot/snapshot.go +++ b/internal/snapshot/snapshot.go @@ -20,6 +20,7 @@ import ( "errors" "fmt" "github.com/echovault/echovault/internal" + "github.com/echovault/echovault/internal/clock" "io" "io/fs" "log" @@ -37,6 +38,7 @@ type Manifest struct { } type Engine struct { + clock clock.Clock changeCount uint64 directory string snapshotInterval time.Duration @@ -49,6 +51,12 @@ type Engine struct { setKeyDataFunc func(key string, data internal.KeyData) } +func WithClock(clock clock.Clock) func(engine *Engine) { + return func(engine *Engine) { + engine.clock = clock + } +} + func WithDirectory(directory string) func(engine *Engine) { return func(engine *Engine) { engine.directory = directory @@ -105,6 +113,7 @@ func WithSetKeyDataFunc(f func(key string, data internal.KeyData)) func(engine * func NewSnapshotEngine(options ...func(engine *Engine)) *Engine { engine := &Engine{ + clock: clock.NewClock(), changeCount: 0, directory: "", snapshotInterval: 5 * time.Minute, @@ -128,7 +137,7 @@ func NewSnapshotEngine(options ...func(engine *Engine)) *Engine { if engine.snapshotInterval != 0 { go func() { for { - <-time.After(engine.snapshotInterval) + <-engine.clock.After(engine.snapshotInterval) if engine.changeCount == engine.snapshotThreshold { if err := engine.TakeSnapshot(); err != nil { log.Println(err) @@ -146,7 +155,7 @@ func (engine *Engine) TakeSnapshot() error { defer engine.finishSnapshotFunc() // Extract current time - now := time.Now() + now := engine.clock.Now() msec := now.UnixNano() / int64(time.Millisecond) // Update manifest file to indicate the latest snapshot. diff --git a/pkg/echovault/api_generic_test.go b/pkg/echovault/api_generic_test.go index c66bb2e..9ec5b45 100644 --- a/pkg/echovault/api_generic_test.go +++ b/pkg/echovault/api_generic_test.go @@ -16,6 +16,7 @@ package echovault import ( "github.com/echovault/echovault/internal" + "github.com/echovault/echovault/internal/clock" "github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/pkg/commands" "github.com/echovault/echovault/pkg/constants" @@ -26,13 +27,6 @@ import ( "time" ) -var timeNow = func() time.Time { - now := time.Now() - return func() time.Time { - return now.Add(5 * time.Hour).Add(30 * time.Minute).Add(30 * time.Second).Add(10 * time.Millisecond) - }() -} - func TestEchoVault_DEL(t *testing.T) { server, _ := NewEchoVault( WithCommands(commands.All()), @@ -81,6 +75,8 @@ func TestEchoVault_DEL(t *testing.T) { } func TestEchoVault_EXPIRE(t *testing.T) { + mockClock := clock.NewClock() + server, _ := NewEchoVault( WithCommands(commands.All()), WithConfig(config.Config{ @@ -142,7 +138,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { time: 1000, expireOpts: EXPIREOptions{NX: true}, presetValues: map[string]internal.KeyData{ - "key4": {Value: "value4", ExpireAt: timeNow().Add(1000 * time.Second)}, + "key4": {Value: "value4", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, want: 0, wantErr: false, @@ -154,7 +150,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { time: 1000, expireOpts: EXPIREOptions{XX: true}, presetValues: map[string]internal.KeyData{ - "key5": {Value: "value5", ExpireAt: timeNow().Add(30 * time.Second)}, + "key5": {Value: "value5", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, want: 1, wantErr: false, @@ -178,7 +174,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { time: 100000, expireOpts: EXPIREOptions{GT: true}, presetValues: map[string]internal.KeyData{ - "key7": {Value: "value7", ExpireAt: timeNow().Add(30 * time.Second)}, + "key7": {Value: "value7", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, want: 1, wantErr: false, @@ -190,7 +186,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { time: 1000, expireOpts: EXPIREOptions{GT: true}, presetValues: map[string]internal.KeyData{ - "key8": {Value: "value8", ExpireAt: timeNow().Add(3000 * time.Second)}, + "key8": {Value: "value8", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, want: 0, wantErr: false, @@ -214,7 +210,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { time: 1000, expireOpts: EXPIREOptions{LT: true}, presetValues: map[string]internal.KeyData{ - "key10": {Value: "value10", ExpireAt: timeNow().Add(3000 * time.Second)}, + "key10": {Value: "value10", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, want: 1, wantErr: false, @@ -226,7 +222,7 @@ func TestEchoVault_EXPIRE(t *testing.T) { time: 50000, expireOpts: EXPIREOptions{LT: true}, presetValues: map[string]internal.KeyData{ - "key11": {Value: "value11", ExpireAt: timeNow().Add(30 * time.Second)}, + "key11": {Value: "value11", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, want: 0, wantErr: false, @@ -258,6 +254,8 @@ func TestEchoVault_EXPIRE(t *testing.T) { } func TestEchoVault_EXPIREAT(t *testing.T) { + mockClock := clock.NewClock() + server, _ := NewEchoVault( WithCommands(commands.All()), WithConfig(config.Config{ @@ -281,7 +279,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { cmd: "EXPIREAT", key: "key1", expireAtOpts: EXPIREATOptions{}, - time: int(timeNow().Add(1000 * time.Second).Unix()), + time: int(mockClock.Now().Add(1000 * time.Second).Unix()), presetValues: map[string]internal.KeyData{ "key1": {Value: "value1", ExpireAt: time.Time{}}, }, @@ -293,7 +291,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { cmd: "PEXPIREAT", key: "key2", pexpireAtOpts: PEXPIREATOptions{}, - time: int(timeNow().Add(1000 * time.Second).UnixMilli()), + time: int(mockClock.Now().Add(1000 * time.Second).UnixMilli()), presetValues: map[string]internal.KeyData{ "key2": {Value: "value2", ExpireAt: time.Time{}}, }, @@ -304,7 +302,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { name: "Set new expire only when key does not have an expiry time with NX flag", cmd: "EXPIREAT", key: "key3", - time: int(timeNow().Add(1000 * time.Second).Unix()), + time: int(mockClock.Now().Add(1000 * time.Second).Unix()), expireAtOpts: EXPIREATOptions{NX: true}, presetValues: map[string]internal.KeyData{ "key3": {Value: "value3", ExpireAt: time.Time{}}, @@ -315,11 +313,11 @@ func TestEchoVault_EXPIREAT(t *testing.T) { { name: "Return 0, when NX flag is provided and key already has an expiry time", cmd: "EXPIREAT", - time: int(timeNow().Add(1000 * time.Second).Unix()), + time: int(mockClock.Now().Add(1000 * time.Second).Unix()), expireAtOpts: EXPIREATOptions{NX: true}, key: "key4", presetValues: map[string]internal.KeyData{ - "key4": {Value: "value4", ExpireAt: timeNow().Add(1000 * time.Second)}, + "key4": {Value: "value4", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, want: 0, wantErr: false, @@ -327,11 +325,11 @@ func TestEchoVault_EXPIREAT(t *testing.T) { { name: "Set new expire time from now key only when the key already has an expiry time with XX flag", cmd: "EXPIREAT", - time: int(timeNow().Add(1000 * time.Second).Unix()), + time: int(mockClock.Now().Add(1000 * time.Second).Unix()), key: "key5", expireAtOpts: EXPIREATOptions{XX: true}, presetValues: map[string]internal.KeyData{ - "key5": {Value: "value5", ExpireAt: timeNow().Add(30 * time.Second)}, + "key5": {Value: "value5", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, want: 1, wantErr: false, @@ -340,7 +338,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { name: "Return 0 when key does not have an expiry and the XX flag is provided", cmd: "EXPIREAT", key: "key6", - time: int(timeNow().Add(1000 * time.Second).Unix()), + time: int(mockClock.Now().Add(1000 * time.Second).Unix()), expireAtOpts: EXPIREATOptions{XX: true}, presetValues: map[string]internal.KeyData{ "key6": {Value: "value6", ExpireAt: time.Time{}}, @@ -352,10 +350,10 @@ func TestEchoVault_EXPIREAT(t *testing.T) { name: "Set expiry time when the provided time is after the current expiry time when GT flag is provided", cmd: "EXPIREAT", key: "key7", - time: int(timeNow().Add(1000 * time.Second).Unix()), + time: int(mockClock.Now().Add(1000 * time.Second).Unix()), expireAtOpts: EXPIREATOptions{GT: true}, presetValues: map[string]internal.KeyData{ - "key7": {Value: "value7", ExpireAt: timeNow().Add(30 * time.Second)}, + "key7": {Value: "value7", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, want: 1, wantErr: false, @@ -364,10 +362,10 @@ func TestEchoVault_EXPIREAT(t *testing.T) { name: "Return 0 when GT flag is passed and current expiry time is greater than provided time", cmd: "EXPIREAT", key: "key8", - time: int(timeNow().Add(1000 * time.Second).Unix()), + time: int(mockClock.Now().Add(1000 * time.Second).Unix()), expireAtOpts: EXPIREATOptions{GT: true}, presetValues: map[string]internal.KeyData{ - "key8": {Value: "value8", ExpireAt: timeNow().Add(3000 * time.Second)}, + "key8": {Value: "value8", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, want: 0, wantErr: false, @@ -376,7 +374,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { name: "Return 0 when GT flag is passed and key does not have an expiry time", cmd: "EXPIREAT", key: "key9", - time: int(timeNow().Add(1000 * time.Second).Unix()), + time: int(mockClock.Now().Add(1000 * time.Second).Unix()), expireAtOpts: EXPIREATOptions{GT: true}, presetValues: map[string]internal.KeyData{ "key9": {Value: "value9", ExpireAt: time.Time{}}, @@ -387,10 +385,10 @@ func TestEchoVault_EXPIREAT(t *testing.T) { name: "Set expiry time when the provided time is before the current expiry time when LT flag is provided", cmd: "EXPIREAT", key: "key10", - time: int(timeNow().Add(1000 * time.Second).Unix()), + time: int(mockClock.Now().Add(1000 * time.Second).Unix()), expireAtOpts: EXPIREATOptions{LT: true}, presetValues: map[string]internal.KeyData{ - "key10": {Value: "value10", ExpireAt: timeNow().Add(3000 * time.Second)}, + "key10": {Value: "value10", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, want: 1, wantErr: false, @@ -399,10 +397,10 @@ func TestEchoVault_EXPIREAT(t *testing.T) { name: "Return 0 when LT flag is passed and current expiry time is less than provided time", cmd: "EXPIREAT", key: "key11", - time: int(timeNow().Add(3000 * time.Second).Unix()), + time: int(mockClock.Now().Add(3000 * time.Second).Unix()), expireAtOpts: EXPIREATOptions{LT: true}, presetValues: map[string]internal.KeyData{ - "key11": {Value: "value11", ExpireAt: timeNow().Add(1000 * time.Second)}, + "key11": {Value: "value11", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, want: 0, wantErr: false, @@ -411,7 +409,7 @@ func TestEchoVault_EXPIREAT(t *testing.T) { name: "Return 0 when LT flag is passed and key does not have an expiry time", cmd: "EXPIREAT", key: "key12", - time: int(timeNow().Add(1000 * time.Second).Unix()), + time: int(mockClock.Now().Add(1000 * time.Second).Unix()), expireAtOpts: EXPIREATOptions{LT: true}, presetValues: map[string]internal.KeyData{ "key12": {Value: "value12", ExpireAt: time.Time{}}, @@ -446,6 +444,8 @@ func TestEchoVault_EXPIREAT(t *testing.T) { } func TestEchoVault_EXPIRETIME(t *testing.T) { + mockClock := clock.NewClock() + server, _ := NewEchoVault( WithCommands(commands.All()), WithConfig(config.Config{ @@ -465,20 +465,20 @@ func TestEchoVault_EXPIRETIME(t *testing.T) { name: "Return expire time in seconds", key: "key1", presetValues: map[string]internal.KeyData{ - "key1": {Value: "value1", ExpireAt: timeNow().Add(100 * time.Second)}, + "key1": {Value: "value1", ExpireAt: mockClock.Now().Add(100 * time.Second)}, }, expiretimeFunc: server.EXPIRETIME, - want: int(timeNow().Add(100 * time.Second).Unix()), + want: int(mockClock.Now().Add(100 * time.Second).Unix()), wantErr: false, }, { name: "Return expire time in milliseconds", key: "key2", presetValues: map[string]internal.KeyData{ - "key2": {Value: "value2", ExpireAt: timeNow().Add(4096 * time.Millisecond)}, + "key2": {Value: "value2", ExpireAt: mockClock.Now().Add(4096 * time.Millisecond)}, }, expiretimeFunc: server.PEXPIRETIME, - want: int(timeNow().Add(4096 * time.Millisecond).UnixMilli()), + want: int(mockClock.Now().Add(4096 * time.Millisecond).UnixMilli()), wantErr: false, }, { @@ -623,6 +623,8 @@ func TestEchoVault_MGET(t *testing.T) { } func TestEchoVault_SET(t *testing.T) { + mockClock := clock.NewClock() + server, _ := NewEchoVault( WithCommands(commands.All()), WithConfig(config.Config{ @@ -717,7 +719,7 @@ func TestEchoVault_SET(t *testing.T) { presetValues: nil, key: "key8", value: "value8", - options: SETOptions{EXAT: int(timeNow().Add(200 * time.Second).Unix())}, + options: SETOptions{EXAT: int(mockClock.Now().Add(200 * time.Second).Unix())}, want: "OK", wantErr: false, }, @@ -725,7 +727,7 @@ func TestEchoVault_SET(t *testing.T) { name: "Set exact expiry time in milliseconds from unix epoch", key: "key9", value: "value9", - options: SETOptions{PXAT: int(timeNow().Add(4096 * time.Millisecond).UnixMilli())}, + options: SETOptions{PXAT: int(mockClock.Now().Add(4096 * time.Millisecond).UnixMilli())}, presetValues: nil, want: "OK", wantErr: false, @@ -809,6 +811,8 @@ func TestEchoVault_MSET(t *testing.T) { } func TestEchoVault_PERSIST(t *testing.T) { + mockClock := clock.NewClock() + server, _ := NewEchoVault( WithCommands(commands.All()), WithConfig(config.Config{ @@ -827,7 +831,7 @@ func TestEchoVault_PERSIST(t *testing.T) { name: "Successfully persist a volatile key", key: "key1", presetValues: map[string]internal.KeyData{ - "key1": {Value: "value1", ExpireAt: timeNow().Add(1000 * time.Second)}, + "key1": {Value: "value1", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, want: true, wantErr: false, @@ -869,6 +873,8 @@ func TestEchoVault_PERSIST(t *testing.T) { } func TestEchoVault_TTL(t *testing.T) { + mockClock := clock.NewClock() + server, _ := NewEchoVault( WithCommands(commands.All()), WithConfig(config.Config{ @@ -888,10 +894,10 @@ func TestEchoVault_TTL(t *testing.T) { name: "Return TTL time in seconds", key: "key1", presetValues: map[string]internal.KeyData{ - "key1": {Value: "value1", ExpireAt: timeNow().Add(100 * time.Second)}, + "key1": {Value: "value1", ExpireAt: mockClock.Now().Add(100 * time.Second)}, }, ttlFunc: server.TTL, - want: 19930, + want: 100, wantErr: false, }, { @@ -899,9 +905,9 @@ func TestEchoVault_TTL(t *testing.T) { key: "key2", ttlFunc: server.PTTL, presetValues: map[string]internal.KeyData{ - "key2": {Value: "value2", ExpireAt: timeNow().Add(4096 * time.Millisecond)}, + "key2": {Value: "value2", ExpireAt: mockClock.Now().Add(4096 * time.Millisecond)}, }, - want: 19834106, + want: 4096, wantErr: false, }, { diff --git a/pkg/echovault/echovault.go b/pkg/echovault/echovault.go index 1f901b7..86024f3 100644 --- a/pkg/echovault/echovault.go +++ b/pkg/echovault/echovault.go @@ -23,6 +23,7 @@ import ( "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/acl" "github.com/echovault/echovault/internal/aof" + "github.com/echovault/echovault/internal/clock" "github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/eviction" "github.com/echovault/echovault/internal/memberlist" @@ -41,6 +42,9 @@ import ( ) type EchoVault struct { + // clock is an implementation of a time interface that allows mocking of time functions during testing. + clock clock.Clock + // config holds the echovault configuration variables. config config.Config @@ -90,8 +94,8 @@ type EchoVault struct { } // WithContext is an options that for the NewEchoVault function that allows you to -// configure a custom context object to be used in EchoVault. If you don't provide this -// option, EchoVault will create its own internal context object. +// configure a custom context object to be used in EchoVault. +// If you don't provide this option, EchoVault will create its own internal context object. func WithContext(ctx context.Context) func(echovault *EchoVault) { return func(echovault *EchoVault) { echovault.context = ctx @@ -99,8 +103,8 @@ func WithContext(ctx context.Context) func(echovault *EchoVault) { } // WithConfig is an option for the NewEchoVault function that allows you to pass a -// custom configuration to EchoVault. If not specified, EchoVault will use the default -// configuration from config.DefaultConfig(). +// custom configuration to EchoVault. +// If not specified, EchoVault will use the default configuration from config.DefaultConfig(). func WithConfig(config config.Config) func(echovault *EchoVault) { return func(echovault *EchoVault) { echovault.config = config @@ -108,8 +112,8 @@ func WithConfig(config config.Config) func(echovault *EchoVault) { } // WithCommands is an options for the NewEchoVault function that allows you to pass a -// list of commands that should be supported by your EchoVault instance. If you don't pass -// this option, EchoVault will start with no commands loaded. +// list of commands that should be supported by your EchoVault instance. +// If you don't pass this option, EchoVault will start with no commands loaded. func WithCommands(commands []types.Command) func(echovault *EchoVault) { return func(echovault *EchoVault) { echovault.commands = commands @@ -120,6 +124,7 @@ func WithCommands(commands []types.Command) func(echovault *EchoVault) { // This functions accepts the WithContext, WithConfig and WithCommands options. func NewEchoVault(options ...func(echovault *EchoVault)) (*EchoVault, error) { echovault := &EchoVault{ + clock: clock.NewClock(), context: context.Background(), commands: make([]types.Command, 0), config: config.DefaultConfig(), @@ -174,6 +179,7 @@ func NewEchoVault(options ...func(echovault *EchoVault)) (*EchoVault, error) { } else { // Set up standalone snapshot engine echovault.snapshotEngine = snapshot.NewSnapshotEngine( + snapshot.WithClock(echovault.clock), snapshot.WithDirectory(echovault.config.DataDir), snapshot.WithThreshold(echovault.config.SnapShotThreshold), snapshot.WithInterval(echovault.config.SnapshotInterval), @@ -204,6 +210,7 @@ func NewEchoVault(options ...func(echovault *EchoVault)) (*EchoVault, error) { ) // Set up standalone AOF engine echovault.aofEngine = aof.NewAOFEngine( + aof.WithClock(echovault.clock), aof.WithDirectory(echovault.config.DataDir), aof.WithStrategy(echovault.config.AOFSyncStrategy), aof.WithStartRewriteFunc(echovault.startRewriteAOF), @@ -241,7 +248,7 @@ func NewEchoVault(options ...func(echovault *EchoVault)) (*EchoVault, error) { if echovault.config.EvictionPolicy != constants.NoEviction { go func() { for { - <-time.After(echovault.config.EvictionInterval) + <-echovault.clock.After(echovault.config.EvictionInterval) if err := echovault.evictKeysWithExpiredTTL(context.Background()); err != nil { log.Println(err) } @@ -465,6 +472,11 @@ func (server *EchoVault) TakeSnapshot() error { return nil } +// GetClock returns the server's clock implementation +func (server *EchoVault) GetClock() clock.Clock { + return server.clock +} + func (server *EchoVault) startSnapshot() { server.snapshotInProgress.Store(true) } diff --git a/pkg/echovault/keyspace.go b/pkg/echovault/keyspace.go index 6608a50..a6ae9ba 100644 --- a/pkg/echovault/keyspace.go +++ b/pkg/echovault/keyspace.go @@ -118,7 +118,7 @@ func (server *EchoVault) KeyExists(ctx context.Context, key string) bool { return false } - if entry.ExpireAt != (time.Time{}) && entry.ExpireAt.Before(time.Now()) { + if entry.ExpireAt != (time.Time{}) && entry.ExpireAt.Before(server.clock.Now()) { if !server.isInCluster() { // If in standalone mode, delete the key directly. err := server.DeleteKey(ctx, key) @@ -553,7 +553,7 @@ func (server *EchoVault) evictKeysWithExpiredTTL(ctx context.Context) error { } // If the current key is not expired, skip to the next key - if server.store[k].ExpireAt.After(time.Now()) { + if server.store[k].ExpireAt.After(server.clock.Now()) { server.KeyRUnlock(ctx, k) continue } diff --git a/pkg/modules/generic/commands.go b/pkg/modules/generic/commands.go index 8f52fa3..21c58d9 100644 --- a/pkg/modules/generic/commands.go +++ b/pkg/modules/generic/commands.go @@ -42,8 +42,9 @@ func handleSet(ctx context.Context, cmd []string, server types.EchoVault, _ *net key := keys[0] value := cmd[2] res := []byte(constants.OkResponse) + clock := server.GetClock() - params, err := getSetCommandParams(cmd[3:], SetParams{}) + params, err := getSetCommandParams(clock, cmd[3:], SetParams{}) if err != nil { return nil, err } @@ -308,6 +309,8 @@ func handleTTL(ctx context.Context, cmd []string, server types.EchoVault, _ *net key := keys[0] + clock := server.GetClock() + if !server.KeyExists(ctx, key) { return []byte(":-2\r\n"), nil } @@ -323,9 +326,9 @@ func handleTTL(ctx context.Context, cmd []string, server types.EchoVault, _ *net return []byte(":-1\r\n"), nil } - t := expireAt.Unix() - time.Now().Unix() + t := expireAt.Unix() - clock.Now().Unix() if strings.ToLower(cmd[0]) == "pttl" { - t = expireAt.UnixMilli() - time.Now().UnixMilli() + t = expireAt.UnixMilli() - clock.Now().UnixMilli() } if t <= 0 { @@ -348,9 +351,9 @@ func handleExpire(ctx context.Context, cmd []string, server types.EchoVault, _ * if err != nil { return nil, errors.New("expire time must be integer") } - expireAt := time.Now().Add(time.Duration(n) * time.Second) + expireAt := server.GetClock().Now().Add(time.Duration(n) * time.Second) if strings.ToLower(cmd[0]) == "pexpire" { - expireAt = time.Now().Add(time.Duration(n) * time.Millisecond) + expireAt = server.GetClock().Now().Add(time.Duration(n) * time.Millisecond) } if !server.KeyExists(ctx, key) { diff --git a/pkg/modules/generic/commands_test.go b/pkg/modules/generic/commands_test.go index 03a588a..2fa5168 100644 --- a/pkg/modules/generic/commands_test.go +++ b/pkg/modules/generic/commands_test.go @@ -19,6 +19,7 @@ import ( "context" "errors" "fmt" + "github.com/echovault/echovault/internal/clock" "github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/pkg/constants" "github.com/echovault/echovault/pkg/echovault" @@ -29,12 +30,16 @@ import ( var mockServer *echovault.EchoVault +var mockClock clock.Clock + type KeyData struct { Value interface{} ExpireAt time.Time } func init() { + mockClock = clock.NewClock() + mockServer, _ = echovault.NewEchoVault( echovault.WithConfig(config.Config{ DataDir: "", @@ -139,7 +144,7 @@ func Test_HandleSET(t *testing.T) { presetValues: nil, expectedResponse: "OK", expectedValue: "value10", - expectedExpiry: time.Now().Add(100 * time.Second), + expectedExpiry: mockClock.Now().Add(100 * time.Second), expectedErr: nil, }, { // 11. Return error when EX flag is passed without seconds value @@ -171,7 +176,7 @@ func Test_HandleSET(t *testing.T) { presetValues: nil, expectedResponse: "OK", expectedValue: "value14", - expectedExpiry: time.Now().Add(4096 * time.Millisecond), + expectedExpiry: mockClock.Now().Add(4096 * time.Millisecond), expectedErr: nil, }, { // 15. Return error when PX flag is passed without milliseconds value @@ -201,19 +206,19 @@ func Test_HandleSET(t *testing.T) { { // 18. Set exact expiry time in seconds from unix epoch command: []string{ "SET", "SetKey18", "value18", - "EXAT", fmt.Sprintf("%d", time.Now().Add(200*time.Second).Unix()), + "EXAT", fmt.Sprintf("%d", mockClock.Now().Add(200*time.Second).Unix()), }, presetValues: nil, expectedResponse: "OK", expectedValue: "value18", - expectedExpiry: time.Now().Add(200 * time.Second), + expectedExpiry: mockClock.Now().Add(200 * time.Second), expectedErr: nil, }, { // 19. Return error when trying to set exact seconds expiry time when expiry time is already provided command: []string{ "SET", "SetKey19", "value19", "EX", "10", - "EXAT", fmt.Sprintf("%d", time.Now().Add(200*time.Second).Unix()), + "EXAT", fmt.Sprintf("%d", mockClock.Now().Add(200*time.Second).Unix()), }, presetValues: nil, expectedResponse: nil, @@ -240,19 +245,19 @@ func Test_HandleSET(t *testing.T) { { // 22. Set exact expiry time in milliseconds from unix epoch command: []string{ "SET", "SetKey22", "value22", - "PXAT", fmt.Sprintf("%d", time.Now().Add(4096*time.Millisecond).UnixMilli()), + "PXAT", fmt.Sprintf("%d", mockClock.Now().Add(4096*time.Millisecond).UnixMilli()), }, presetValues: nil, expectedResponse: "OK", expectedValue: "value22", - expectedExpiry: time.Now().Add(4096 * time.Millisecond), + expectedExpiry: mockClock.Now().Add(4096 * time.Millisecond), expectedErr: nil, }, { // 23. Return error when trying to set exact milliseconds expiry time when expiry time is already provided command: []string{ "SET", "SetKey23", "value23", "PX", "1000", - "PXAT", fmt.Sprintf("%d", time.Now().Add(4096*time.Millisecond).UnixMilli()), + "PXAT", fmt.Sprintf("%d", mockClock.Now().Add(4096*time.Millisecond).UnixMilli()), }, presetValues: nil, expectedResponse: nil, @@ -286,7 +291,7 @@ func Test_HandleSET(t *testing.T) { }, expectedResponse: "previous-value", expectedValue: "value26", - expectedExpiry: time.Now().Add(1000 * time.Second), + expectedExpiry: mockClock.Now().Add(1000 * time.Second), expectedErr: nil, }, { // 27. Return nil when GET value is passed and no previous value exists @@ -294,7 +299,7 @@ func Test_HandleSET(t *testing.T) { presetValues: nil, expectedResponse: nil, expectedValue: "value27", - expectedExpiry: time.Now().Add(1000 * time.Second), + expectedExpiry: mockClock.Now().Add(1000 * time.Second), expectedErr: nil, }, { // 28. Throw error when unknown optional flag is passed to SET command. @@ -320,7 +325,7 @@ func Test_HandleSET(t *testing.T) { } for i, test := range tests { - ctx := context.WithValue(context.Background(), "test_name", fmt.Sprintf("SET, %d", i)) + ctx := context.WithValue(context.Background(), "test_name", fmt.Sprintf("SET, %d", i+1)) if test.presetValues != nil { for k, v := range test.presetValues { @@ -384,7 +389,7 @@ func Test_HandleSET(t *testing.T) { t.Errorf("expected value %+v, got %+v", test.expectedValue, value) } if test.expectedExpiry.Unix() != expireAt.Unix() { - t.Errorf("expected expiry time %d, got %d", test.expectedExpiry.Unix(), expireAt.Unix()) + t.Errorf("expected expiry time %d, got %d, cmd: %+v", test.expectedExpiry.Unix(), expireAt.Unix(), test.command) } } } @@ -714,7 +719,7 @@ func Test_HandlePERSIST(t *testing.T) { { // 1. Successfully persist a volatile key command: []string{"PERSIST", "PersistKey1"}, presetValues: map[string]KeyData{ - "PersistKey1": {Value: "value1", ExpireAt: time.Now().Add(1000 * time.Second)}, + "PersistKey1": {Value: "value1", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, expectedResponse: 1, expectedValues: map[string]KeyData{ @@ -827,17 +832,17 @@ func Test_HandleEXPIRETIME(t *testing.T) { { // 1. Return expire time in seconds command: []string{"EXPIRETIME", "ExpireTimeKey1"}, presetValues: map[string]KeyData{ - "ExpireTimeKey1": {Value: "value1", ExpireAt: time.Now().Add(100 * time.Second)}, + "ExpireTimeKey1": {Value: "value1", ExpireAt: mockClock.Now().Add(100 * time.Second)}, }, - expectedResponse: int(time.Now().Add(100 * time.Second).Unix()), + expectedResponse: int(mockClock.Now().Add(100 * time.Second).Unix()), expectedError: nil, }, { // 2. Return expire time in milliseconds command: []string{"PEXPIRETIME", "ExpireTimeKey2"}, presetValues: map[string]KeyData{ - "ExpireTimeKey2": {Value: "value2", ExpireAt: time.Now().Add(4096 * time.Millisecond)}, + "ExpireTimeKey2": {Value: "value2", ExpireAt: mockClock.Now().Add(4096 * time.Millisecond)}, }, - expectedResponse: int(time.Now().Add(4096 * time.Millisecond).UnixMilli()), + expectedResponse: int(mockClock.Now().Add(4096 * time.Millisecond).UnixMilli()), expectedError: nil, }, { // 3. If the key is non-volatile, return -1 @@ -920,7 +925,7 @@ func Test_HandleTTL(t *testing.T) { { // 1. Return TTL time in seconds command: []string{"TTL", "TTLKey1"}, presetValues: map[string]KeyData{ - "TTLKey1": {Value: "value1", ExpireAt: time.Now().Add(100 * time.Second)}, + "TTLKey1": {Value: "value1", ExpireAt: mockClock.Now().Add(100 * time.Second)}, }, expectedResponse: 100, expectedError: nil, @@ -928,7 +933,7 @@ func Test_HandleTTL(t *testing.T) { { // 2. Return TTL time in milliseconds command: []string{"PTTL", "TTLKey2"}, presetValues: map[string]KeyData{ - "TTLKey2": {Value: "value2", ExpireAt: time.Now().Add(4096 * time.Millisecond)}, + "TTLKey2": {Value: "value2", ExpireAt: mockClock.Now().Add(4096 * time.Millisecond)}, }, expectedResponse: 4096, expectedError: nil, @@ -1018,7 +1023,7 @@ func Test_HandleEXPIRE(t *testing.T) { }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireKey1": {Value: "value1", ExpireAt: time.Now().Add(100 * time.Second)}, + "ExpireKey1": {Value: "value1", ExpireAt: mockClock.Now().Add(100 * time.Second)}, }, expectedError: nil, }, @@ -1029,7 +1034,7 @@ func Test_HandleEXPIRE(t *testing.T) { }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireKey2": {Value: "value2", ExpireAt: time.Now().Add(1000 * time.Millisecond)}, + "ExpireKey2": {Value: "value2", ExpireAt: mockClock.Now().Add(1000 * time.Millisecond)}, }, expectedError: nil, }, @@ -1040,29 +1045,29 @@ func Test_HandleEXPIRE(t *testing.T) { }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireKey3": {Value: "value3", ExpireAt: time.Now().Add(1000 * time.Second)}, + "ExpireKey3": {Value: "value3", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, expectedError: nil, }, { // 4. Return 0, when NX flag is provided and key already has an expiry time command: []string{"EXPIRE", "ExpireKey4", "1000", "NX"}, presetValues: map[string]KeyData{ - "ExpireKey4": {Value: "value4", ExpireAt: time.Now().Add(1000 * time.Second)}, + "ExpireKey4": {Value: "value4", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, expectedResponse: 0, expectedValues: map[string]KeyData{ - "ExpireKey4": {Value: "value4", ExpireAt: time.Now().Add(1000 * time.Second)}, + "ExpireKey4": {Value: "value4", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, expectedError: nil, }, { // 5. Set new expire time from now key only when the key already has an expiry time with XX flag command: []string{"EXPIRE", "ExpireKey5", "1000", "XX"}, presetValues: map[string]KeyData{ - "ExpireKey5": {Value: "value5", ExpireAt: time.Now().Add(30 * time.Second)}, + "ExpireKey5": {Value: "value5", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireKey5": {Value: "value5", ExpireAt: time.Now().Add(1000 * time.Second)}, + "ExpireKey5": {Value: "value5", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, expectedError: nil, }, @@ -1080,22 +1085,22 @@ func Test_HandleEXPIRE(t *testing.T) { { // 7. Set expiry time when the provided time is after the current expiry time when GT flag is provided command: []string{"EXPIRE", "ExpireKey7", "1000", "GT"}, presetValues: map[string]KeyData{ - "ExpireKey7": {Value: "value7", ExpireAt: time.Now().Add(30 * time.Second)}, + "ExpireKey7": {Value: "value7", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireKey7": {Value: "value7", ExpireAt: time.Now().Add(1000 * time.Second)}, + "ExpireKey7": {Value: "value7", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, expectedError: nil, }, { // 8. Return 0 when GT flag is passed and current expiry time is greater than provided time command: []string{"EXPIRE", "ExpireKey8", "1000", "GT"}, presetValues: map[string]KeyData{ - "ExpireKey8": {Value: "value8", ExpireAt: time.Now().Add(3000 * time.Second)}, + "ExpireKey8": {Value: "value8", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, expectedResponse: 0, expectedValues: map[string]KeyData{ - "ExpireKey8": {Value: "value8", ExpireAt: time.Now().Add(3000 * time.Second)}, + "ExpireKey8": {Value: "value8", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, expectedError: nil, }, @@ -1113,22 +1118,22 @@ func Test_HandleEXPIRE(t *testing.T) { { // 10. Set expiry time when the provided time is before the current expiry time when LT flag is provided command: []string{"EXPIRE", "ExpireKey10", "1000", "LT"}, presetValues: map[string]KeyData{ - "ExpireKey10": {Value: "value10", ExpireAt: time.Now().Add(3000 * time.Second)}, + "ExpireKey10": {Value: "value10", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireKey10": {Value: "value10", ExpireAt: time.Now().Add(1000 * time.Second)}, + "ExpireKey10": {Value: "value10", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, expectedError: nil, }, { // 11. Return 0 when LT flag is passed and current expiry time is less than provided time command: []string{"EXPIRE", "ExpireKey11", "5000", "LT"}, presetValues: map[string]KeyData{ - "ExpireKey11": {Value: "value11", ExpireAt: time.Now().Add(3000 * time.Second)}, + "ExpireKey11": {Value: "value11", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, expectedResponse: 0, expectedValues: map[string]KeyData{ - "ExpireKey11": {Value: "value11", ExpireAt: time.Now().Add(3000 * time.Second)}, + "ExpireKey11": {Value: "value11", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, expectedError: nil, }, @@ -1139,7 +1144,7 @@ func Test_HandleEXPIRE(t *testing.T) { }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireKey12": {Value: "value12", ExpireAt: time.Now().Add(1000 * time.Second)}, + "ExpireKey12": {Value: "value12", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, expectedError: nil, }, @@ -1245,67 +1250,67 @@ func Test_HandleEXPIREAT(t *testing.T) { expectedError error }{ { // 1. Set new expire by unix seconds - command: []string{"EXPIREAT", "ExpireAtKey1", fmt.Sprintf("%d", time.Now().Add(1000*time.Second).Unix())}, + command: []string{"EXPIREAT", "ExpireAtKey1", fmt.Sprintf("%d", mockClock.Now().Add(1000*time.Second).Unix())}, presetValues: map[string]KeyData{ "ExpireAtKey1": {Value: "value1", ExpireAt: time.Time{}}, }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireAtKey1": {Value: "value1", ExpireAt: time.Unix(time.Now().Add(1000*time.Second).Unix(), 0)}, + "ExpireAtKey1": {Value: "value1", ExpireAt: time.Unix(mockClock.Now().Add(1000*time.Second).Unix(), 0)}, }, expectedError: nil, }, { // 2. Set new expire by milliseconds - command: []string{"PEXPIREAT", "ExpireAtKey2", fmt.Sprintf("%d", time.Now().Add(1000*time.Second).UnixMilli())}, + command: []string{"PEXPIREAT", "ExpireAtKey2", fmt.Sprintf("%d", mockClock.Now().Add(1000*time.Second).UnixMilli())}, presetValues: map[string]KeyData{ "ExpireAtKey2": {Value: "value2", ExpireAt: time.Time{}}, }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireAtKey2": {Value: "value2", ExpireAt: time.UnixMilli(time.Now().Add(1000 * time.Second).UnixMilli())}, + "ExpireAtKey2": {Value: "value2", ExpireAt: time.UnixMilli(mockClock.Now().Add(1000 * time.Second).UnixMilli())}, }, expectedError: nil, }, { // 3. Set new expire only when key does not have an expiry time with NX flag - command: []string{"EXPIREAT", "ExpireAtKey3", fmt.Sprintf("%d", time.Now().Add(1000*time.Second).Unix()), "NX"}, + command: []string{"EXPIREAT", "ExpireAtKey3", fmt.Sprintf("%d", mockClock.Now().Add(1000*time.Second).Unix()), "NX"}, presetValues: map[string]KeyData{ "ExpireAtKey3": {Value: "value3", ExpireAt: time.Time{}}, }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireAtKey3": {Value: "value3", ExpireAt: time.Unix(time.Now().Add(1000*time.Second).Unix(), 0)}, + "ExpireAtKey3": {Value: "value3", ExpireAt: time.Unix(mockClock.Now().Add(1000*time.Second).Unix(), 0)}, }, expectedError: nil, }, { // 4. Return 0, when NX flag is provided and key already has an expiry time - command: []string{"EXPIREAT", "ExpireAtKey4", fmt.Sprintf("%d", time.Now().Add(1000*time.Second).Unix()), "NX"}, + command: []string{"EXPIREAT", "ExpireAtKey4", fmt.Sprintf("%d", mockClock.Now().Add(1000*time.Second).Unix()), "NX"}, presetValues: map[string]KeyData{ - "ExpireAtKey4": {Value: "value4", ExpireAt: time.Now().Add(1000 * time.Second)}, + "ExpireAtKey4": {Value: "value4", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, expectedResponse: 0, expectedValues: map[string]KeyData{ - "ExpireAtKey4": {Value: "value4", ExpireAt: time.Now().Add(1000 * time.Second)}, + "ExpireAtKey4": {Value: "value4", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, expectedError: nil, }, { // 5. Set new expire time from now key only when the key already has an expiry time with XX flag command: []string{ "EXPIREAT", "ExpireAtKey5", - fmt.Sprintf("%d", time.Now().Add(1000*time.Second).Unix()), "XX", + fmt.Sprintf("%d", mockClock.Now().Add(1000*time.Second).Unix()), "XX", }, presetValues: map[string]KeyData{ - "ExpireAtKey5": {Value: "value5", ExpireAt: time.Now().Add(30 * time.Second)}, + "ExpireAtKey5": {Value: "value5", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireAtKey5": {Value: "value5", ExpireAt: time.Unix(time.Now().Add(1000*time.Second).Unix(), 0)}, + "ExpireAtKey5": {Value: "value5", ExpireAt: time.Unix(mockClock.Now().Add(1000*time.Second).Unix(), 0)}, }, expectedError: nil, }, { // 6. Return 0 when key does not have an expiry and the XX flag is provided command: []string{ "EXPIREAT", "ExpireAtKey6", - fmt.Sprintf("%d", time.Now().Add(1000*time.Second).Unix()), "XX", + fmt.Sprintf("%d", mockClock.Now().Add(1000*time.Second).Unix()), "XX", }, presetValues: map[string]KeyData{ "ExpireAtKey6": {Value: "value6", ExpireAt: time.Time{}}, @@ -1319,35 +1324,35 @@ func Test_HandleEXPIREAT(t *testing.T) { { // 7. Set expiry time when the provided time is after the current expiry time when GT flag is provided command: []string{ "EXPIREAT", "ExpireAtKey7", - fmt.Sprintf("%d", time.Now().Add(1000*time.Second).Unix()), "GT", + fmt.Sprintf("%d", mockClock.Now().Add(1000*time.Second).Unix()), "GT", }, presetValues: map[string]KeyData{ - "ExpireAtKey7": {Value: "value7", ExpireAt: time.Now().Add(30 * time.Second)}, + "ExpireAtKey7": {Value: "value7", ExpireAt: mockClock.Now().Add(30 * time.Second)}, }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireAtKey7": {Value: "value7", ExpireAt: time.Unix(time.Now().Add(1000*time.Second).Unix(), 0)}, + "ExpireAtKey7": {Value: "value7", ExpireAt: time.Unix(mockClock.Now().Add(1000*time.Second).Unix(), 0)}, }, expectedError: nil, }, { // 8. Return 0 when GT flag is passed and current expiry time is greater than provided time command: []string{ "EXPIREAT", "ExpireAtKey8", - fmt.Sprintf("%d", time.Now().Add(1000*time.Second).Unix()), "GT", + fmt.Sprintf("%d", mockClock.Now().Add(1000*time.Second).Unix()), "GT", }, presetValues: map[string]KeyData{ - "ExpireAtKey8": {Value: "value8", ExpireAt: time.Now().Add(3000 * time.Second)}, + "ExpireAtKey8": {Value: "value8", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, expectedResponse: 0, expectedValues: map[string]KeyData{ - "ExpireAtKey8": {Value: "value8", ExpireAt: time.Now().Add(3000 * time.Second)}, + "ExpireAtKey8": {Value: "value8", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, expectedError: nil, }, { // 9. Return 0 when GT flag is passed and key does not have an expiry time command: []string{ "EXPIREAT", "ExpireAtKey9", - fmt.Sprintf("%d", time.Now().Add(1000*time.Second).Unix()), "GT", + fmt.Sprintf("%d", mockClock.Now().Add(1000*time.Second).Unix()), "GT", }, presetValues: map[string]KeyData{ "ExpireAtKey9": {Value: "value9", ExpireAt: time.Time{}}, @@ -1361,42 +1366,42 @@ func Test_HandleEXPIREAT(t *testing.T) { { // 10. Set expiry time when the provided time is before the current expiry time when LT flag is provided command: []string{ "EXPIREAT", "ExpireAtKey10", - fmt.Sprintf("%d", time.Now().Add(1000*time.Second).Unix()), "LT", + fmt.Sprintf("%d", mockClock.Now().Add(1000*time.Second).Unix()), "LT", }, presetValues: map[string]KeyData{ - "ExpireAtKey10": {Value: "value10", ExpireAt: time.Now().Add(3000 * time.Second)}, + "ExpireAtKey10": {Value: "value10", ExpireAt: mockClock.Now().Add(3000 * time.Second)}, }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireAtKey10": {Value: "value10", ExpireAt: time.Unix(time.Now().Add(1000*time.Second).Unix(), 0)}, + "ExpireAtKey10": {Value: "value10", ExpireAt: time.Unix(mockClock.Now().Add(1000*time.Second).Unix(), 0)}, }, expectedError: nil, }, { // 11. Return 0 when LT flag is passed and current expiry time is less than provided time command: []string{ "EXPIREAT", "ExpireAtKey11", - fmt.Sprintf("%d", time.Now().Add(3000*time.Second).Unix()), "LT", + fmt.Sprintf("%d", mockClock.Now().Add(3000*time.Second).Unix()), "LT", }, presetValues: map[string]KeyData{ - "ExpireAtKey11": {Value: "value11", ExpireAt: time.Now().Add(1000 * time.Second)}, + "ExpireAtKey11": {Value: "value11", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, expectedResponse: 0, expectedValues: map[string]KeyData{ - "ExpireAtKey11": {Value: "value11", ExpireAt: time.Now().Add(1000 * time.Second)}, + "ExpireAtKey11": {Value: "value11", ExpireAt: mockClock.Now().Add(1000 * time.Second)}, }, expectedError: nil, }, { // 12. Return 0 when LT flag is passed and key does not have an expiry time command: []string{ "EXPIREAT", "ExpireAtKey12", - fmt.Sprintf("%d", time.Now().Add(1000*time.Second).Unix()), "LT", + fmt.Sprintf("%d", mockClock.Now().Add(1000*time.Second).Unix()), "LT", }, presetValues: map[string]KeyData{ "ExpireAtKey12": {Value: "value12", ExpireAt: time.Time{}}, }, expectedResponse: 1, expectedValues: map[string]KeyData{ - "ExpireAtKey12": {Value: "value12", ExpireAt: time.Unix(time.Now().Add(1000*time.Second).Unix(), 0)}, + "ExpireAtKey12": {Value: "value12", ExpireAt: time.Unix(mockClock.Now().Add(1000*time.Second).Unix(), 0)}, }, expectedError: nil, }, diff --git a/pkg/modules/generic/utils.go b/pkg/modules/generic/utils.go index bf5992a..17a3f5d 100644 --- a/pkg/modules/generic/utils.go +++ b/pkg/modules/generic/utils.go @@ -17,6 +17,7 @@ package generic import ( "errors" "fmt" + "github.com/echovault/echovault/internal/clock" "strconv" "strings" "time" @@ -28,28 +29,28 @@ type SetParams struct { expireAt interface{} // Exact expireAt time un unix milliseconds } -func getSetCommandParams(cmd []string, params SetParams) (SetParams, error) { +func getSetCommandParams(clock clock.Clock, cmd []string, params SetParams) (SetParams, error) { if len(cmd) == 0 { return params, nil } switch strings.ToLower(cmd[0]) { case "get": params.get = true - return getSetCommandParams(cmd[1:], params) + return getSetCommandParams(clock, cmd[1:], params) case "nx": if params.exists != "" { return SetParams{}, fmt.Errorf("cannot specify NX when %s is already specified", strings.ToUpper(params.exists)) } params.exists = "NX" - return getSetCommandParams(cmd[1:], params) + return getSetCommandParams(clock, cmd[1:], params) case "xx": if params.exists != "" { return SetParams{}, fmt.Errorf("cannot specify XX when %s is already specified", strings.ToUpper(params.exists)) } params.exists = "XX" - return getSetCommandParams(cmd[1:], params) + return getSetCommandParams(clock, cmd[1:], params) case "ex": if len(cmd) < 2 { @@ -63,8 +64,8 @@ func getSetCommandParams(cmd []string, params SetParams) (SetParams, error) { if err != nil { return SetParams{}, errors.New("seconds value should be an integer") } - params.expireAt = time.Now().Add(time.Duration(seconds) * time.Second) - return getSetCommandParams(cmd[2:], params) + params.expireAt = clock.Now().Add(time.Duration(seconds) * time.Second) + return getSetCommandParams(clock, cmd[2:], params) case "px": if len(cmd) < 2 { @@ -78,8 +79,8 @@ func getSetCommandParams(cmd []string, params SetParams) (SetParams, error) { if err != nil { return SetParams{}, errors.New("milliseconds value should be an integer") } - params.expireAt = time.Now().Add(time.Duration(milliseconds) * time.Millisecond) - return getSetCommandParams(cmd[2:], params) + params.expireAt = clock.Now().Add(time.Duration(milliseconds) * time.Millisecond) + return getSetCommandParams(clock, cmd[2:], params) case "exat": if len(cmd) < 2 { @@ -94,7 +95,7 @@ func getSetCommandParams(cmd []string, params SetParams) (SetParams, error) { return SetParams{}, errors.New("seconds value should be an integer") } params.expireAt = time.Unix(seconds, 0) - return getSetCommandParams(cmd[2:], params) + return getSetCommandParams(clock, cmd[2:], params) case "pxat": if len(cmd) < 2 { @@ -109,7 +110,7 @@ func getSetCommandParams(cmd []string, params SetParams) (SetParams, error) { return SetParams{}, errors.New("milliseconds value should be an integer") } params.expireAt = time.UnixMilli(milliseconds) - return getSetCommandParams(cmd[2:], params) + return getSetCommandParams(clock, cmd[2:], params) default: return SetParams{}, fmt.Errorf("unknown option %s for set command", strings.ToUpper(cmd[0])) diff --git a/pkg/types/types.go b/pkg/types/types.go index b2644cf..b831706 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -16,6 +16,7 @@ package types import ( "context" + "github.com/echovault/echovault/internal/clock" "net" "time" ) @@ -33,6 +34,7 @@ type EchoVault interface { SetExpiry(ctx context.Context, key string, expire time.Time, touch bool) RemoveExpiry(key string) DeleteKey(ctx context.Context, key string) error + GetClock() clock.Clock GetAllCommands() []Command GetACL() interface{} GetPubSub() interface{}