Skip to content

Commit 1883c90

Browse files
authored
Merge pull request #7 from Rich-T-kid/pre-release
feat(GRPC-spec): define grpc contract between Query parser and query …
2 parents 25aea9d + 6b744fe commit 1883c90

29 files changed

+4471
-22
lines changed

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,12 @@ flycheck0/
9494
# Cache directories
9595
.cache/
9696
node_modules/
97+
98+
# dont push large files to git
99+
src/Backend/test_data/parquet
100+
src/Backend/test_data/csv
101+
src/Backend/test_data/json
102+
103+
# Allow s3_source directory
104+
!src/Backend/test_data/s3_source/
105+
!src/Backend/test_data/s3_source/**

README.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ OptiSQL is a custom in-memory query execution engine. The backend (physical exec
1919
### Prerequisites
2020
- Go 1.24+
2121
- Rust 1.70+
22-
- C++ (marco update this)
22+
- C++23
2323
- Make
2424
- git
2525

@@ -72,7 +72,6 @@ Initial development is done in **Go** (`opti-sql-go`), which serves as the prima
7272
- `/operators` - SQL operator implementations (filter, join, aggregation, project)
7373
- `/physical-optimizer` - Query plan parsing and optimization
7474
- `/substrait` - Substrait plan integration
75-
- `/project` - [Add description]
7675

7776
## Branching Model
7877

@@ -130,6 +129,4 @@ Want to contribute? Check out [CONTRIBUTING.md](CONTRIBUTING.md) for detailed gu
130129
- Build and run instructions
131130

132131
## License
133-
134-
This project is licensed under the terms specified in [LICENSE.txt](LICENSE.txt).
135-
132+
This project is licensed under the terms specified in [LICENSE.txt](LICENSE.txt).
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package config
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"os"
7+
"strings"
8+
9+
"gopkg.in/yaml.v3"
10+
)
11+
12+
var (
13+
kiloByte = 1024
14+
megaByte = 1024 * kiloByte
15+
gigaByte = 1024 * megaByte
16+
)
17+
18+
type Config struct {
19+
Server serverConfig `yaml:"server"`
20+
Batch batchConfig `yaml:"batch"`
21+
Query queryConfig `yaml:"query"`
22+
Metrics metricsConfig `yaml:"metrics"`
23+
}
24+
type serverConfig struct {
25+
Port int `yaml:"port"`
26+
Host string `yaml:"host"`
27+
Timeout int `yaml:"timeout"`
28+
MaxRequestSizeMB uint64 `yaml:"max_request_size_mb"` // max size of a file upload. passed in by grpc request
29+
}
30+
type batchConfig struct {
31+
Size int `yaml:"size"`
32+
EnableParallelRead bool `yaml:"enable_parallel_read"`
33+
MaxMemoryBeforeSpill uint64 `yaml:"max_memory_before_spill"`
34+
MaxFileSizeMB int `yaml:"max_file_size_mb"` // max size of a single file
35+
}
36+
type queryConfig struct {
37+
// should results be cached, server side? if so how long
38+
EnableCache bool `yaml:"enable_cache"`
39+
CacheTTLSeconds int `yaml:"cache_ttl_seconds"`
40+
// run queries concurrently? if so what the max before blocking
41+
EnableConcurrentExecution bool `yaml:"enable_concurrent_execution"`
42+
MaxConcurrentQueries int `yaml:"max_concurrent_queries"` // blocks after this many concurrent queries until one finishes
43+
}
44+
type metricsConfig struct {
45+
EnableMetrics bool `yaml:"enable_metrics"`
46+
MetricsPort int `yaml:"metrics_port"`
47+
MetricsHost string `yaml:"metrics_host"`
48+
ExportIntervalSecs int `yaml:"export_interval_secs"`
49+
// what queries have beeen sent
50+
EnableQueryStats bool `yaml:"enable_query_stats"`
51+
// memory usage over time
52+
EnableMemoryStats bool `yaml:"enable_memory_stats"`
53+
}
54+
55+
var configInstance *Config = &Config{
56+
Server: serverConfig{
57+
Port: 8080,
58+
Host: "localhost",
59+
Timeout: 30,
60+
MaxRequestSizeMB: 15,
61+
},
62+
Batch: batchConfig{
63+
Size: 1024 * 8, // rows per bathch
64+
EnableParallelRead: true,
65+
MaxMemoryBeforeSpill: uint64(gigaByte) * 2, // 2GB
66+
MaxFileSizeMB: 500, // 500MB
67+
},
68+
Query: queryConfig{
69+
EnableCache: true,
70+
CacheTTLSeconds: 600, // 10 minutes
71+
EnableConcurrentExecution: true,
72+
MaxConcurrentQueries: 2, // 2 concurrent queries
73+
},
74+
Metrics: metricsConfig{
75+
EnableMetrics: true,
76+
MetricsPort: 9999,
77+
MetricsHost: "localhost",
78+
ExportIntervalSecs: 60, // 1 minute
79+
EnableQueryStats: true,
80+
EnableMemoryStats: true,
81+
},
82+
}
83+
84+
func GetConfig() *Config {
85+
return configInstance
86+
}
87+
88+
// overwrite global instance with loaded config
89+
func Decode(filePath string) error {
90+
suffix := strings.Split(filePath, ".")[len(strings.Split(filePath, "."))-1]
91+
if suffix != "yaml" && suffix != "yml" {
92+
return errors.New("file must be a .yaml or .yml file")
93+
}
94+
r, err := os.Open(filePath)
95+
if err != nil {
96+
return err
97+
}
98+
config := make(map[string]interface{})
99+
decoder := yaml.NewDecoder(r)
100+
if err := decoder.Decode(config); err != nil {
101+
return fmt.Errorf("failed to decode config: %w", err)
102+
}
103+
mergeConfig(configInstance, config)
104+
return nil
105+
}
106+
func mergeConfig(dst *Config, src map[string]interface{}) {
107+
// =============================
108+
// SERVER
109+
// =============================
110+
if server, ok := src["server"].(map[string]interface{}); ok {
111+
if v, ok := server["port"].(int); ok {
112+
dst.Server.Port = v
113+
}
114+
if v, ok := server["host"].(string); ok {
115+
dst.Server.Host = v
116+
}
117+
if v, ok := server["timeout"].(int); ok {
118+
dst.Server.Timeout = v
119+
}
120+
if v, ok := server["max_request_size_mb"].(int); ok {
121+
dst.Server.MaxRequestSizeMB = uint64(v)
122+
}
123+
}
124+
125+
// =============================
126+
// BATCH
127+
// =============================
128+
if batch, ok := src["batch"].(map[string]interface{}); ok {
129+
if v, ok := batch["size"].(int); ok {
130+
dst.Batch.Size = v
131+
}
132+
if v, ok := batch["enable_parallel_read"].(bool); ok {
133+
dst.Batch.EnableParallelRead = v
134+
}
135+
if v, ok := batch["max_memory_before_spill"].(int); ok {
136+
dst.Batch.MaxMemoryBeforeSpill = uint64(v)
137+
}
138+
if v, ok := batch["max_file_size_mb"].(int); ok {
139+
dst.Batch.MaxFileSizeMB = v
140+
}
141+
}
142+
143+
// =============================
144+
// QUERY
145+
// =============================
146+
if query, ok := src["query"].(map[string]interface{}); ok {
147+
if v, ok := query["enable_cache"].(bool); ok {
148+
dst.Query.EnableCache = v
149+
}
150+
if v, ok := query["cache_ttl_seconds"].(int); ok {
151+
dst.Query.CacheTTLSeconds = v
152+
}
153+
if v, ok := query["enable_concurrent_execution"].(bool); ok {
154+
dst.Query.EnableConcurrentExecution = v
155+
}
156+
if v, ok := query["max_concurrent_queries"].(int); ok {
157+
dst.Query.MaxConcurrentQueries = v
158+
}
159+
}
160+
161+
// =============================
162+
// METRICS
163+
// =============================
164+
if metrics, ok := src["metrics"].(map[string]interface{}); ok {
165+
if v, ok := metrics["enable_metrics"].(bool); ok {
166+
dst.Metrics.EnableMetrics = v
167+
}
168+
if v, ok := metrics["metrics_port"].(int); ok {
169+
dst.Metrics.MetricsPort = v
170+
}
171+
if v, ok := metrics["metrics_host"].(string); ok {
172+
dst.Metrics.MetricsHost = v
173+
}
174+
if v, ok := metrics["export_interval_secs"].(int); ok {
175+
dst.Metrics.ExportIntervalSecs = v
176+
}
177+
if v, ok := metrics["enable_query_stats"].(bool); ok {
178+
dst.Metrics.EnableQueryStats = v
179+
}
180+
if v, ok := metrics["enable_memory_stats"].(bool); ok {
181+
dst.Metrics.EnableMemoryStats = v
182+
}
183+
}
184+
}

0 commit comments

Comments
 (0)