@@ -276,14 +276,15 @@ func (db *CertDatabase) GetLogState(aUrl *url.URL) (*types.CTLogState, error) {
276
276
}, nil
277
277
}
278
278
279
- func (db * CertDatabase ) Store ( aCert * x509. Certificate , aIssuer * x509.Certificate ) error {
280
- expDate := types .NewExpDateFromTime (aCert .NotAfter )
279
+ func (db * CertDatabase ) PrepareSetMember ( aCertificate , aIssuer * x509.Certificate ) SetMemberWithExpiry {
280
+ expDate := types .NewExpDateFromTime (aCertificate .NotAfter )
281
281
issuer := types .NewIssuer (aIssuer )
282
- serialWriter := db . GetSerialCacheAccessor ( expDate , issuer )
283
-
284
- serial := types . NewSerial ( aCert )
282
+ serial := types . NewSerial ( aCertificate )
283
+ return db . GetSerialCacheKey ( expDate , issuer ). NewMember ( serial )
284
+ }
285
285
286
- _ , err := serialWriter .Insert (serial )
286
+ func (db * CertDatabase ) Store (items []SetMemberWithExpiry ) error {
287
+ err := db .cache .SetInsertMany (items )
287
288
if err != nil {
288
289
return err
289
290
}
@@ -330,15 +331,15 @@ func (db *CertDatabase) GetCTLogsFromStorage() ([]types.CTLogState, error) {
330
331
return ctLogList , nil
331
332
}
332
333
333
- func (db * CertDatabase ) GetSerialCacheAccessor (aExpDate types.ExpDate , aIssuer types.Issuer ) * SerialCacheWriter {
334
- var kc * SerialCacheWriter
334
+ func (db * CertDatabase ) GetSerialCacheKey (aExpDate types.ExpDate , aIssuer types.Issuer ) * SerialCacheKey {
335
+ var kc * SerialCacheKey
335
336
336
337
id := aIssuer .ID () + aExpDate .ID ()
337
338
338
339
cacheObj , err := db .cacheAccessors .GetIFPresent (id )
339
340
if err != nil {
340
341
if err == gcache .KeyNotFoundError {
341
- kc = NewSerialCacheWriter (aExpDate , aIssuer , db . cache )
342
+ kc = NewSerialCacheKey (aExpDate , aIssuer )
342
343
err = db .cacheAccessors .Set (id , kc )
343
344
if err != nil {
344
345
glog .Fatalf ("Couldn't set into the cache expDate=%s issuer=%s from cache: %s" ,
@@ -349,7 +350,7 @@ func (db *CertDatabase) GetSerialCacheAccessor(aExpDate types.ExpDate, aIssuer t
349
350
aExpDate , aIssuer .ID (), err )
350
351
}
351
352
} else {
352
- kc = cacheObj .(* SerialCacheWriter )
353
+ kc = cacheObj .(* SerialCacheKey )
353
354
}
354
355
355
356
if kc == nil {
@@ -359,8 +360,7 @@ func (db *CertDatabase) GetSerialCacheAccessor(aExpDate types.ExpDate, aIssuer t
359
360
}
360
361
361
362
func (db * CertDatabase ) ReadSerialsFromCache (aExpDate types.ExpDate , aIssuer types.Issuer ) []types.Serial {
362
- accessor := db .GetSerialCacheAccessor (aExpDate , aIssuer )
363
- return accessor .List ()
363
+ return db .List (db .GetSerialCacheKey (aExpDate , aIssuer ))
364
364
}
365
365
366
366
func (db * CertDatabase ) ReadSerialsFromStorage (aExpDate types.ExpDate , aIssuer types.Issuer ) ([]types.Serial , error ) {
@@ -434,8 +434,8 @@ func (db *CertDatabase) moveOneBinOfCachedSerialsToStorage(aTmpDir string, aExpD
434
434
}
435
435
436
436
// It's now safe to remove cachedSerials from the cache.
437
- cacheWriter := db .GetSerialCacheAccessor (aExpDate , aIssuer )
438
- err = cacheWriter .RemoveMany (cachedSerials )
437
+ key := db .GetSerialCacheKey (aExpDate , aIssuer )
438
+ err = db .RemoveMany (key , cachedSerials )
439
439
if err != nil {
440
440
glog .Warningf ("Failed to remove serial from cache: %s" , err )
441
441
}
@@ -698,3 +698,68 @@ func (db *CertDatabase) Commit(aProofOfLock string) error {
698
698
func (db * CertDatabase ) AddPreIssuerAlias (aPreIssuer types.Issuer , aIssuer types.Issuer ) error {
699
699
return db .cache .AddPreIssuerAlias (aPreIssuer , aIssuer )
700
700
}
701
+
702
+ // Returns true if this serial was unknown. Subsequent calls with the same serial
703
+ // will return false, as it will be known then.
704
+ func (db * CertDatabase ) Insert (k * SerialCacheKey , aSerial types.Serial ) (bool , error ) {
705
+ result , err := db .cache .SetInsert (k .ID (), aSerial .BinaryString ())
706
+ if err != nil {
707
+ return false , err
708
+ }
709
+
710
+ if ! k .expirySet {
711
+ expireTime := k .expDate .ExpireTime ()
712
+ if err := db .cache .ExpireAt (k .ID (), expireTime ); err != nil {
713
+ glog .Errorf ("Couldn't set expiration time %v for serials %s: %v" , expireTime , k .ID (), err )
714
+ } else {
715
+ k .expirySet = true
716
+ }
717
+ }
718
+
719
+ return result , nil
720
+ }
721
+
722
+ func (db * CertDatabase ) RemoveMany (k * SerialCacheKey , aSerials []types.Serial ) error {
723
+ // Removing an element of a set may leave the set empty. Redis
724
+ // automatically deletes empty sets, so assume that we need to reset
725
+ // the ExpireAt time for this set on the next Insert call.
726
+ k .expirySet = false
727
+ serialStrings := make ([]string , len (aSerials ))
728
+ for i := 0 ; i < len (aSerials ); i ++ {
729
+ serialStrings [i ] = aSerials [i ].BinaryString ()
730
+ }
731
+ return db .cache .SetRemove (k .ID (), serialStrings )
732
+ }
733
+
734
+ func (db * CertDatabase ) List (k * SerialCacheKey ) []types.Serial {
735
+ // Redis' scan methods regularly provide duplicates. The duplication
736
+ // happens at this level, pulling from SetToChan, so we make a hash-set
737
+ // here to de-duplicate when the memory impacts are the most minimal.
738
+ serials := make (map [string ]struct {})
739
+ var count int
740
+
741
+ strChan := make (chan string )
742
+ go func () {
743
+ err := db .cache .SetToChan (k .ID (), strChan )
744
+ if err != nil {
745
+ glog .Fatalf ("Error obtaining list of known certificates: %v" , err )
746
+ }
747
+ }()
748
+
749
+ for str := range strChan {
750
+ serials [str ] = struct {}{}
751
+ count += 1
752
+ }
753
+
754
+ serialList := make ([]types.Serial , 0 , count )
755
+ for str := range serials {
756
+ bs , err := types .NewSerialFromBinaryString (str )
757
+ if err != nil {
758
+ glog .Errorf ("Failed to populate serial str=[%s] %v" , str , err )
759
+ continue
760
+ }
761
+ serialList = append (serialList , bs )
762
+ }
763
+
764
+ return serialList
765
+ }
0 commit comments