Skip to content

Commit 7bb27c5

Browse files
authored
Merge pull request #79 from TykTechnologies/initial-code-push
push initial code
2 parents 821e2bd + 94d4ace commit 7bb27c5

File tree

1,358 files changed

+136548
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,358 files changed

+136548
-0
lines changed

DatabaseCalculator.mdx

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
export const DatabaseCalculator = () => {
2+
const [values, setValues] = useState({
3+
database_type: 'mysql',
4+
storage_size: 100,
5+
storage_unit: 'GB',
6+
concurrent_connections: 100,
7+
queries_per_second: 1000,
8+
backup_frequency: 'daily',
9+
replication_factor: 1
10+
});
11+
12+
const [results, setResults] = useState({});
13+
14+
const handleChange = (name, value) => {
15+
setValues(prev => ({
16+
...prev,
17+
[name]: value
18+
}));
19+
};
20+
21+
const calculate = () => {
22+
const storageBytes = values.storage_size * (values.storage_unit === 'GB' ? 1024 * 1024 * 1024 : 1024 * 1024);
23+
24+
// Database-specific multipliers for resource requirements
25+
const dbMultipliers = {
26+
mysql: { cpu: 1.0, memory: 1.0, storage: 1.0 },
27+
postgresql: { cpu: 1.2, memory: 1.3, storage: 1.1 },
28+
mongodb: { cpu: 1.1, memory: 1.5, storage: 1.2 },
29+
redis: { cpu: 0.8, memory: 2.0, storage: 0.5 },
30+
cassandra: { cpu: 1.3, memory: 1.4, storage: 1.5 }
31+
};
32+
33+
const multiplier = dbMultipliers[values.database_type] || dbMultipliers.mysql;
34+
35+
// Calculate resource requirements
36+
const baseMemoryGB = Math.max(2, (values.concurrent_connections * 0.01) + (values.queries_per_second * 0.001));
37+
const recommendedMemoryGB = baseMemoryGB * multiplier.memory * values.replication_factor;
38+
39+
const baseCPUCores = Math.max(2, (values.queries_per_second * 0.0001) + (values.concurrent_connections * 0.001));
40+
const recommendedCPUCores = baseCPUCores * multiplier.cpu;
41+
42+
const totalStorageGB = (storageBytes / (1024 * 1024 * 1024)) * multiplier.storage * values.replication_factor;
43+
44+
// Backup storage calculation
45+
const backupMultiplier = values.backup_frequency === 'hourly' ? 24 : values.backup_frequency === 'daily' ? 7 : 4;
46+
const backupStorageGB = totalStorageGB * 0.3 * backupMultiplier; // Assume 30% compression
47+
48+
setResults({
49+
recommended_memory: recommendedMemoryGB,
50+
recommended_cpu: recommendedCPUCores,
51+
total_storage: totalStorageGB,
52+
backup_storage: backupStorageGB,
53+
total_storage_with_backup: totalStorageGB + backupStorageGB
54+
});
55+
};
56+
57+
useEffect(() => {
58+
calculate();
59+
}, [values]);
60+
61+
const databaseTypes = [
62+
{ value: 'mysql', label: 'MySQL' },
63+
{ value: 'postgresql', label: 'PostgreSQL' },
64+
{ value: 'mongodb', label: 'MongoDB' },
65+
{ value: 'redis', label: 'Redis' },
66+
{ value: 'cassandra', label: 'Cassandra' }
67+
];
68+
69+
const storageUnits = [
70+
{ value: 'MB', label: 'MB' },
71+
{ value: 'GB', label: 'GB' }
72+
];
73+
74+
const backupFrequencies = [
75+
{ value: 'hourly', label: 'Hourly' },
76+
{ value: 'daily', label: 'Daily' },
77+
{ value: 'weekly', label: 'Weekly' }
78+
];
79+
80+
const inputFields = [
81+
{
82+
name: 'database_type',
83+
label: 'Database Type',
84+
type: 'select',
85+
options: databaseTypes,
86+
description: 'The type of database system you are planning to use.'
87+
},
88+
{
89+
name: 'storage_size',
90+
label: 'Storage Size',
91+
type: 'number',
92+
unit: values.storage_unit,
93+
description: 'The amount of storage space required for your database.'
94+
},
95+
{
96+
name: 'storage_unit',
97+
label: 'Storage Unit',
98+
type: 'select',
99+
options: storageUnits,
100+
description: 'The unit of measurement for storage size.'
101+
},
102+
{
103+
name: 'concurrent_connections',
104+
label: 'Concurrent Connections',
105+
type: 'number',
106+
unit: 'Connections',
107+
description: 'The maximum number of simultaneous database connections.'
108+
},
109+
{
110+
name: 'queries_per_second',
111+
label: 'Queries Per Second',
112+
type: 'number',
113+
unit: 'QPS',
114+
description: 'The expected number of database queries per second.'
115+
},
116+
{
117+
name: 'backup_frequency',
118+
label: 'Backup Frequency',
119+
type: 'select',
120+
options: backupFrequencies,
121+
description: 'How often you plan to create database backups.'
122+
},
123+
{
124+
name: 'replication_factor',
125+
label: 'Replication Factor',
126+
type: 'number',
127+
unit: 'Replicas',
128+
description: 'The number of database replicas for high availability.'
129+
}
130+
];
131+
132+
const resultFields = [
133+
{ name: 'recommended_memory', label: 'Recommended Memory', unit: 'GB', description: 'The recommended amount of RAM for optimal performance.' },
134+
{ name: 'recommended_cpu', label: 'Recommended CPU Cores', unit: 'Cores', description: 'The recommended number of CPU cores.' },
135+
{ name: 'total_storage', label: 'Total Storage Required', unit: 'GB', description: 'The total storage space required including replication.' },
136+
{ name: 'backup_storage', label: 'Backup Storage', unit: 'GB', description: 'Additional storage required for backups.' },
137+
{ name: 'total_storage_with_backup', label: 'Total with Backups', unit: 'GB', description: 'Total storage including backup space.' }
138+
];
139+
140+
return (
141+
<div style={{
142+
maxWidth: '800px',
143+
margin: '0 auto',
144+
padding: '20px',
145+
fontFamily: 'system-ui, -apple-system, sans-serif'
146+
}}>
147+
<div style={{
148+
backgroundColor: '#f8f9fa',
149+
border: '1px solid #e9ecef',
150+
borderRadius: '8px',
151+
padding: '24px',
152+
marginBottom: '24px'
153+
}}>
154+
<h3 style={{
155+
margin: '0 0 20px 0',
156+
color: '#495057',
157+
fontSize: '1.25rem',
158+
fontWeight: '600'
159+
}}>
160+
Database Sizing Calculator
161+
</h3>
162+
163+
<div style={{ marginBottom: '24px' }}>
164+
<h4 style={{
165+
margin: '0 0 16px 0',
166+
color: '#6c757d',
167+
fontSize: '1rem',
168+
fontWeight: '500'
169+
}}>
170+
Input Parameters
171+
</h4>
172+
173+
<div style={{
174+
display: 'grid',
175+
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
176+
gap: '16px'
177+
}}>
178+
{inputFields.map(field => (
179+
<div key={field.name} style={{ marginBottom: '12px' }}>
180+
<div style={{
181+
display: 'flex',
182+
alignItems: 'center',
183+
marginBottom: '4px'
184+
}}>
185+
<label
186+
htmlFor={field.name}
187+
title={field.description}
188+
style={{
189+
marginRight: 'auto',
190+
fontSize: '0.875rem',
191+
fontWeight: '500',
192+
color: '#495057'
193+
}}
194+
>
195+
{field.label}
196+
</label>
197+
198+
{field.type === 'select' ? (
199+
<select
200+
id={field.name}
201+
name={field.name}
202+
value={values[field.name]}
203+
onChange={(e) => handleChange(field.name, e.target.value)}
204+
title={field.description}
205+
style={{
206+
margin: '0 10px',
207+
padding: '6px 8px',
208+
border: '1px solid #ced4da',
209+
borderRadius: '4px',
210+
fontSize: '0.875rem',
211+
width: '120px'
212+
}}
213+
>
214+
{field.options.map(option => (
215+
<option key={option.value} value={option.value}>
216+
{option.label}
217+
</option>
218+
))}
219+
</select>
220+
) : (
221+
<input
222+
id={field.name}
223+
name={field.name}
224+
type="number"
225+
value={values[field.name]}
226+
onChange={(e) => handleChange(field.name, parseFloat(e.target.value) || 0)}
227+
title={field.description}
228+
required
229+
style={{
230+
margin: '0 10px',
231+
padding: '6px 8px',
232+
border: '1px solid #ced4da',
233+
borderRadius: '4px',
234+
fontSize: '0.875rem',
235+
width: '80px'
236+
}}
237+
/>
238+
)}
239+
240+
<label style={{
241+
width: '80px',
242+
fontSize: '0.875rem',
243+
color: '#6c757d'
244+
}}>
245+
{field.unit || ''}
246+
</label>
247+
</div>
248+
</div>
249+
))}
250+
</div>
251+
</div>
252+
253+
<hr style={{ margin: '24px 0', border: 'none', borderTop: '1px solid #dee2e6' }} />
254+
255+
<div>
256+
<h4 style={{
257+
margin: '0 0 16px 0',
258+
color: '#6c757d',
259+
fontSize: '1rem',
260+
fontWeight: '500'
261+
}}>
262+
Calculated Results
263+
</h4>
264+
265+
<div style={{
266+
display: 'grid',
267+
gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
268+
gap: '16px'
269+
}}>
270+
{resultFields.map(field => (
271+
<div key={field.name} style={{ marginBottom: '12px' }}>
272+
<div style={{
273+
display: 'flex',
274+
alignItems: 'center',
275+
marginBottom: '4px'
276+
}}>
277+
<label
278+
title={field.description}
279+
style={{
280+
marginRight: 'auto',
281+
fontSize: '0.875rem',
282+
fontWeight: '500',
283+
color: '#495057'
284+
}}
285+
>
286+
{field.label}
287+
</label>
288+
<input
289+
type="text"
290+
value={(results[field.name] || 0).toFixed(2)}
291+
disabled
292+
title={field.description}
293+
style={{
294+
margin: '0 10px',
295+
padding: '6px 8px',
296+
border: '1px solid #ced4da',
297+
borderRadius: '4px',
298+
fontSize: '0.875rem',
299+
width: '80px',
300+
backgroundColor: '#f8f9fa',
301+
color: '#495057'
302+
}}
303+
/>
304+
<label style={{
305+
width: '80px',
306+
fontSize: '0.875rem',
307+
color: '#6c757d'
308+
}}>
309+
{field.unit}
310+
</label>
311+
</div>
312+
</div>
313+
))}
314+
</div>
315+
</div>
316+
</div>
317+
</div>
318+
);
319+
};

0 commit comments

Comments
 (0)