implement event table subtyping for small events in value log
This commit is contained in:
@@ -15,47 +15,92 @@ import (
|
||||
func (d *D) FetchEventsBySerials(serials []*types.Uint40) (events map[uint64]*event.E, err error) {
|
||||
// Pre-allocate map with estimated capacity to reduce reallocations
|
||||
events = make(map[uint64]*event.E, len(serials))
|
||||
|
||||
|
||||
if len(serials) == 0 {
|
||||
return events, nil
|
||||
}
|
||||
|
||||
|
||||
if err = d.View(
|
||||
func(txn *badger.Txn) (err error) {
|
||||
for _, ser := range serials {
|
||||
var ev *event.E
|
||||
|
||||
// Try sev (small event inline) prefix first - Reiser4 optimization
|
||||
smallBuf := new(bytes.Buffer)
|
||||
if err = indexes.SmallEventEnc(ser).MarshalWrite(smallBuf); chk.E(err) {
|
||||
// Skip this serial on error but continue with others
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
|
||||
// Iterate with prefix to find the small event key
|
||||
opts := badger.DefaultIteratorOptions
|
||||
opts.Prefix = smallBuf.Bytes()
|
||||
opts.PrefetchValues = true
|
||||
opts.PrefetchSize = 1
|
||||
it := txn.NewIterator(opts)
|
||||
|
||||
it.Rewind()
|
||||
if it.Valid() {
|
||||
// Found in sev table - extract inline data
|
||||
key := it.Item().Key()
|
||||
// Key format: sev|serial|size_uint16|event_data
|
||||
if len(key) > 8+2 { // prefix(3) + serial(5) + size(2) = 10 bytes minimum
|
||||
sizeIdx := 8 // After sev(3) + serial(5)
|
||||
// Read uint16 big-endian size
|
||||
size := int(key[sizeIdx])<<8 | int(key[sizeIdx+1])
|
||||
dataStart := sizeIdx + 2
|
||||
|
||||
if len(key) >= dataStart+size {
|
||||
eventData := key[dataStart : dataStart+size]
|
||||
ev = new(event.E)
|
||||
if err = ev.UnmarshalBinary(bytes.NewBuffer(eventData)); err == nil {
|
||||
events[ser.Get()] = ev
|
||||
}
|
||||
// Clean up and continue
|
||||
it.Close()
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
it.Close()
|
||||
|
||||
// Not found in sev table, try evt (traditional) prefix
|
||||
buf := new(bytes.Buffer)
|
||||
if err = indexes.EventEnc(ser).MarshalWrite(buf); chk.E(err) {
|
||||
// Skip this serial on error but continue with others
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
var item *badger.Item
|
||||
if item, err = txn.Get(buf.Bytes()); err != nil {
|
||||
// Skip this serial if not found but continue with others
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
var v []byte
|
||||
if v, err = item.ValueCopy(nil); chk.E(err) {
|
||||
// Skip this serial on error but continue with others
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
// Check if we have valid data before attempting to unmarshal
|
||||
if len(v) < 32+32+1+2+1+1+64 { // ID + Pubkey + min varint fields + Sig
|
||||
// Skip this serial - incomplete data
|
||||
continue
|
||||
}
|
||||
|
||||
ev := new(event.E)
|
||||
|
||||
ev = new(event.E)
|
||||
if err = ev.UnmarshalBinary(bytes.NewBuffer(v)); err != nil {
|
||||
// Skip this serial on unmarshal error but continue with others
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
// Successfully unmarshaled event, add to results
|
||||
events[ser.Get()] = ev
|
||||
}
|
||||
@@ -64,6 +109,6 @@ func (d *D) FetchEventsBySerials(serials []*types.Uint40) (events map[uint64]*ev
|
||||
); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
return events, nil
|
||||
}
|
||||
Reference in New Issue
Block a user