11#![ cfg( any( feature = "db" , feature = "all" ) ) ]
2- use std:: { borrow:: Cow , io} ;
2+ use std:: { borrow:: Cow , io, ptr } ;
33use std:: fmt:: Arguments ;
44use std:: io:: Write ;
55use std:: mem:: MaybeUninit ;
66use std:: rc:: Rc ;
77use std:: cell:: UnsafeCell ;
8+ use std:: collections:: HashMap ;
89use bytes:: Buf ;
910use nanorand:: { Rng , WyRand } ;
10- use tokio_postgres:: { connect, Client , Statement , NoTls } ;
11+ use tokio_postgres:: { connect, Client , Statement , NoTls , Error } ;
1112use tokio_postgres:: types:: private:: BytesMut ;
1213use crate :: models:: { Fortune , FortuneTemplate , World } ;
1314use sonic_rs:: prelude:: WriteExt ;
1415use yarte:: TemplateBytesTrait ;
16+ pub static mut CACHED_VALUES : Option < HashMap < i32 , i32 > > = None ;
1517
1618/// Database connection pool with thread-local RNG
1719pub struct DbConnectionPool {
@@ -60,8 +62,6 @@ impl DbConnectionPool {
6062/// Reusable buffer pool per connection
6163struct BufferPool {
6264 body : BytesMut ,
63- worlds : Vec < World > ,
64- numbers : Vec < i32 > ,
6565 fortunes : Vec < Fortune > ,
6666 fortune_output : Vec < u8 > ,
6767}
@@ -70,8 +70,6 @@ impl BufferPool {
7070 fn new ( ) -> Self {
7171 Self {
7272 body : BytesMut :: with_capacity ( 4096 ) ,
73- worlds : Vec :: with_capacity ( 501 ) ,
74- numbers : Vec :: with_capacity ( 501 ) ,
7573
7674 fortunes : Vec :: with_capacity ( 501 ) ,
7775 fortune_output : Vec :: with_capacity ( 4096 ) ,
@@ -130,7 +128,7 @@ impl PgConnection {
130128 } /// Connect to the database
131129
132130 #[ inline( always) ]
133- pub fn generate_update_values_stmt ( batch_size : usize ) -> String {
131+ pub fn generate_update_values_stmt ( batch_size : usize ) -> String {
134132
135133 let mut sql = String :: from ( "UPDATE world SET randomNumber = w.r FROM (VALUES " ) ;
136134
@@ -156,38 +154,34 @@ impl PgConnection {
156154 /// Get a single random world - optimized with buffer reuse
157155 #[ inline]
158156 pub async fn get_world ( & self ) -> & [ u8 ] {
159- let rd = ( self . rang . clone ( ) . generate :: < u32 > ( ) % 10_000 + 1 ) as i32 ;
157+ let rd = ( self . rang . clone ( ) . generate :: < u32 > ( ) % 10_000 ) as i32 ;
160158 let row = self . cl . query_one ( & self . world , & [ & rd] ) . await . unwrap ( ) ;
161-
162159 let buffers = self . buffers ( ) ;
163160 buffers. body . clear ( ) ;
164-
165161 sonic_rs:: to_writer (
166162 BytesMuteWriter ( & mut buffers. body ) ,
167163 & World {
168164 id : row. get ( 0 ) ,
169165 randomnumber : row. get ( 1 ) ,
170166 } ,
171167 ) . unwrap ( ) ;
172-
173168 buffers. body . chunk ( )
174169 }
175170
176171 /// Get multiple random worlds - optimized with buffer reuse
177172 pub async fn get_worlds ( & self , num : usize ) -> & [ u8 ] {
178173 let buffers = self . buffers ( ) ;
179- buffers. worlds . clear ( ) ;
180- let mut rn = self . rang . clone ( ) ;
174+ let mut worlds = Vec :: with_capacity ( num) ;
181175 for _ in 0 ..num {
182- let id: i32 = ( rn . generate :: < u32 > ( ) & 0x3FFF ) as i32 % 10_000 + 1 ;
176+ let id = ( self . rang . clone ( ) . generate :: < u32 > ( ) % 10_000 ) as i32 ;
183177 let row = self . cl . query_one ( & self . world , & [ & id] ) . await . unwrap ( ) ;
184- buffers . worlds . push ( World {
178+ worlds. push ( World {
185179 id : row. get ( 0 ) ,
186180 randomnumber : row. get ( 1 ) ,
187181 } ) ;
188182 }
189183 buffers. body . clear ( ) ;
190- sonic_rs:: to_writer ( BytesMuteWriter ( & mut buffers. body ) , & buffers . worlds ) . unwrap ( ) ;
184+ sonic_rs:: to_writer ( BytesMuteWriter ( & mut buffers. body ) , & worlds) . unwrap ( ) ;
191185 buffers. body . chunk ( )
192186 }
193187 /// Update worlds in batch - optimized with buffer reuse
@@ -215,23 +209,24 @@ impl PgConnection {
215209 futures. extend ( ids. iter ( ) . map ( |x| async move { self . cl . query_one ( & self . world , & [ & x] ) . await } ) ) ;
216210 futures_util:: future:: join_all ( futures) . await ;
217211 ids. sort_unstable ( ) ;
218- buffers. worlds . clear ( ) ;
212+ let mut worlds = Vec :: with_capacity ( num) ;
213+ let mut numbers = Vec :: with_capacity ( num) ;
219214 for index in 0 ..num {
220215 let s_id = ( rng. generate :: < u32 > ( ) % 10_000 + 1 ) as i32 ;
221- buffers . worlds . push ( World {
216+ worlds. push ( World {
222217 id : ids[ index] ,
223218 randomnumber : s_id
224219 } ) ;
225- buffers . numbers . push ( s_id) ;
220+ numbers. push ( s_id) ;
226221 }
227222 buffers. body . clear ( ) ;
228223 for index in 0 ..num {
229224 params. push ( & ids[ index] ) ;
230- params. push ( & buffers . numbers [ index] ) ;
225+ params. push ( & numbers[ index] ) ;
231226 }
232227
233228 _=self . cl . execute ( & self . updates [ num - 1 ] , & params) . await . unwrap ( ) ;
234- sonic_rs:: to_writer ( BytesMuteWriter ( & mut buffers. body ) , & buffers . worlds ) . unwrap ( ) ;
229+ sonic_rs:: to_writer ( BytesMuteWriter ( & mut buffers. body ) , & worlds) . unwrap ( ) ;
235230 buffers. body . chunk ( )
236231 }
237232
@@ -264,11 +259,50 @@ impl PgConnection {
264259 // Return reference to buffer - zero-copy!
265260 Ok ( & buffers. fortune_output )
266261 }
262+
263+
264+ pub fn get_cached_queries ( & self , num : usize ) ->& [ u8 ] {
265+ let buf = self . buffers ( ) ;
266+ let buf = & mut buf. body ;
267+ buf. clear ( ) ;
268+ buf. extend_from_slice ( br#"["# ) ;
269+ let mut writer = BytesMuteWriter ( buf) ;
270+ for _ in 0 ..num {
271+ let rd = ( self . rang . clone ( ) . generate :: < u32 > ( ) % 10_000 ) as i32 ;
272+ let v = match self . get_world_id_for_cache ( rd) {
273+ None => { continue }
274+ Some ( e) =>{ e}
275+ } ;
276+ writer. extend_from_slice ( br"{" ) ;
277+ _ = write ! ( writer, r#""id":{},"randomnumber":{}"# , rd, v) ;
278+ writer. extend_from_slice ( br"}," ) ;
279+ }
280+ if buf. len ( ) >1 { buf. truncate ( buf. len ( ) - 1 ) ; }
281+ buf. extend_from_slice ( b"]" ) ;
282+ return & buf[ ..]
283+ }
284+
285+ fn get_world_id_for_cache ( & self , id : i32 ) -> Option < & i32 > {
286+ unsafe {
287+ let ptr = ptr:: addr_of!( CACHED_VALUES ) ;
288+
289+ match & * ptr {
290+ Some ( map) => map. get ( & id) ,
291+ None => None ,
292+ }
293+ }
294+ }
267295}
268296
269297/// Zero-copy writer for BytesMut
270298pub struct BytesMuteWriter < ' a > ( pub & ' a mut BytesMut ) ;
299+ impl BytesMuteWriter < ' _ > {
271300
301+ #[ inline( always) ]
302+ pub fn extend_from_slice ( & mut self , data : & [ u8 ] ) {
303+ self . 0 . extend_from_slice ( data) ;
304+ }
305+ }
272306impl Write for BytesMuteWriter < ' _ > {
273307 #[ inline( always) ]
274308 fn write ( & mut self , src : & [ u8 ] ) -> Result < usize , io:: Error > {
0 commit comments