1+ import Atomics
12import Dflat
23import Dispatch
34import FlatBuffers
@@ -12,6 +13,7 @@ struct SQLiteWorkspaceDictionary: WorkspaceDictionary {
1213 let namespace : String
1314 var locks : UnsafeMutablePointer < os_unfair_lock_s >
1415 var dictionaries : [ [ String : Any ] ]
16+ var disableDiskFetch = UnsafeAtomic< Bool> . Storage( false )
1517 init ( namespace: String ) {
1618 self . namespace = namespace
1719 locks = UnsafeMutablePointer . allocate ( capacity: Self . size)
@@ -99,6 +101,12 @@ struct SQLiteWorkspaceDictionary: WorkspaceDictionary {
99101 return value is None ? nil : ( value as! T )
100102 } // Otherwise, try to load from disk.
101103 storage. unlock ( tuple. 1 )
104+ // Don't need to fetch from disk if it is disabled.
105+ guard
106+ !( withUnsafeMutablePointer ( to: & storage. disableDiskFetch) {
107+ UnsafeAtomic ( at: $0) . load ( ordering: . acquiring)
108+ } )
109+ else { return nil }
102110 if let value = workspace. fetch ( for: DictItem . self) . where (
103111 DictItem . key == key && DictItem . namespace == storage. namespace
104112 ) . first {
@@ -164,6 +172,12 @@ struct SQLiteWorkspaceDictionary: WorkspaceDictionary {
164172 return value is None ? nil : ( value as! Bool )
165173 } // Otherwise, try to load from disk.
166174 storage. unlock ( tuple. 1 )
175+ // Don't need to fetch from disk if it is disabled.
176+ guard
177+ !( withUnsafeMutablePointer ( to: & storage. disableDiskFetch) {
178+ UnsafeAtomic ( at: $0) . load ( ordering: . acquiring)
179+ } )
180+ else { return nil }
167181 if let value = workspace. fetch ( for: DictItem . self) . where (
168182 DictItem . key == key && DictItem . namespace == storage. namespace
169183 ) . first {
@@ -213,6 +227,12 @@ struct SQLiteWorkspaceDictionary: WorkspaceDictionary {
213227 return value is None ? nil : ( value as! Int )
214228 } // Otherwise, try to load from disk.
215229 storage. unlock ( tuple. 1 )
230+ // Don't need to fetch from disk if it is disabled.
231+ guard
232+ !( withUnsafeMutablePointer ( to: & storage. disableDiskFetch) {
233+ UnsafeAtomic ( at: $0) . load ( ordering: . acquiring)
234+ } )
235+ else { return nil }
216236 if let value = workspace. fetch ( for: DictItem . self) . where (
217237 DictItem . key == key && DictItem . namespace == storage. namespace
218238 ) . first {
@@ -262,6 +282,12 @@ struct SQLiteWorkspaceDictionary: WorkspaceDictionary {
262282 return value is None ? nil : ( value as! UInt )
263283 } // Otherwise, try to load from disk.
264284 storage. unlock ( tuple. 1 )
285+ // Don't need to fetch from disk if it is disabled.
286+ guard
287+ !( withUnsafeMutablePointer ( to: & storage. disableDiskFetch) {
288+ UnsafeAtomic ( at: $0) . load ( ordering: . acquiring)
289+ } )
290+ else { return nil }
265291 if let value = workspace. fetch ( for: DictItem . self) . where (
266292 DictItem . key == key && DictItem . namespace == storage. namespace
267293 ) . first {
@@ -312,6 +338,12 @@ struct SQLiteWorkspaceDictionary: WorkspaceDictionary {
312338 return value is None ? nil : ( value as! Float )
313339 } // Otherwise, try to load from disk.
314340 storage. unlock ( tuple. 1 )
341+ // Don't need to fetch from disk if it is disabled.
342+ guard
343+ !( withUnsafeMutablePointer ( to: & storage. disableDiskFetch) {
344+ UnsafeAtomic ( at: $0) . load ( ordering: . acquiring)
345+ } )
346+ else { return nil }
315347 if let value = workspace. fetch ( for: DictItem . self) . where (
316348 DictItem . key == key && DictItem . namespace == storage. namespace
317349 ) . first {
@@ -361,6 +393,12 @@ struct SQLiteWorkspaceDictionary: WorkspaceDictionary {
361393 return value is None ? nil : ( value as! Double )
362394 } // Otherwise, try to load from disk.
363395 storage. unlock ( tuple. 1 )
396+ // Don't need to fetch from disk if it is disabled.
397+ guard
398+ !( withUnsafeMutablePointer ( to: & storage. disableDiskFetch) {
399+ UnsafeAtomic ( at: $0) . load ( ordering: . acquiring)
400+ } )
401+ else { return nil }
364402 if let value = workspace. fetch ( for: DictItem . self) . where (
365403 DictItem . key == key && DictItem . namespace == storage. namespace
366404 ) . first {
@@ -410,6 +448,12 @@ struct SQLiteWorkspaceDictionary: WorkspaceDictionary {
410448 return value is None ? nil : ( value as! String )
411449 } // Otherwise, try to load from disk.
412450 storage. unlock ( tuple. 1 )
451+ // Don't need to fetch from disk if it is disabled.
452+ guard
453+ !( withUnsafeMutablePointer ( to: & storage. disableDiskFetch) {
454+ UnsafeAtomic ( at: $0) . load ( ordering: . acquiring)
455+ } )
456+ else { return nil }
413457 if let value = workspace. fetch ( for: DictItem . self) . where (
414458 DictItem . key == key && DictItem . namespace == storage. namespace
415459 ) . first {
@@ -464,8 +508,14 @@ struct SQLiteWorkspaceDictionary: WorkspaceDictionary {
464508 }
465509
466510 var keys : [ String ] {
467- let items = workspace. fetch ( for: DictItem . self) . where ( DictItem . namespace == storage. namespace)
468- var keys = Set ( items. map { $0. key } )
511+ var keys = Set < String > ( )
512+ // Only need to fetch from disk if it is not disabled.
513+ if !( withUnsafeMutablePointer ( to: & storage. disableDiskFetch) {
514+ UnsafeAtomic ( at: $0) . load ( ordering: . acquiring)
515+ } ) {
516+ let items = workspace. fetch ( for: DictItem . self) . where ( DictItem . namespace == storage. namespace)
517+ keys = Set ( items. map { $0. key } )
518+ }
469519 for i in 0 ..< Storage . size {
470520 storage. lock ( i)
471521 defer { storage. unlock ( i) }
@@ -482,28 +532,22 @@ struct SQLiteWorkspaceDictionary: WorkspaceDictionary {
482532 }
483533
484534 func removeAll( ) {
485- let namespace = storage. namespace
486- let items = workspace. fetch ( for: DictItem . self) . where ( DictItem . namespace == namespace)
487- var keys = [ [ String] ] ( repeating: [ ] , count: Storage . size)
488- for key in items. lazy. map ( \. key) {
489- var hasher = Hasher ( )
490- key. hash ( into: & hasher)
491- let hashValue = Int ( UInt ( bitPattern: hasher. finalize ( ) ) % UInt( Storage . size) )
492- keys [ hashValue] . append ( key)
493- }
494535 for i in 0 ..< Storage . size {
495536 storage. lock ( i)
496537 defer { storage. unlock ( i) }
497538 // Set existing ones in the dictionaries to be None.
498539 for key in storage. dictionaries [ i] . keys {
499540 storage. dictionaries [ i] [ key] = None . none
500541 }
501- // Set the ones fetched from disk to be None.
502- for key in keys [ i] {
503- storage. dictionaries [ i] [ key] = None . none
504- }
542+ }
543+ // Since removed everything from disk. We no longer need to fetch from disk in case
544+ // of a miss any more (because the only thing accessible is write to the in-memory
545+ // data structure first).
546+ withUnsafeMutablePointer ( to: & storage. disableDiskFetch) {
547+ UnsafeAtomic ( at: $0) . store ( true , ordering: . releasing)
505548 }
506549 let workspace = self . workspace
550+ let namespace = storage. namespace
507551 workspace. performChanges (
508552 [ DictItem . self] ,
509553 changesHandler: { txnContext in
0 commit comments