package mmm import ( "os" "path/filepath" "fiatjaf.com/nostr/eventstore" "github.com/PowerDNS/lmdb-go/lmdb" ) var _ eventstore.Store = (*IndexingLayer)(nil) type IndexingLayer struct { isInitialized bool name string mmmm *MultiMmapManager // this is stored in the knownLayers db as a value, and used to keep track of which layer owns each event id uint16 lmdbEnv *lmdb.Env settings lmdb.DBI indexCreatedAt lmdb.DBI indexKind lmdb.DBI indexPubkey lmdb.DBI indexPubkeyKind lmdb.DBI indexTag lmdb.DBI indexTag32 lmdb.DBI indexTagAddr lmdb.DBI indexPTagKind lmdb.DBI } type IndexingLayers []*IndexingLayer func (ils IndexingLayers) ByID(ilid uint16) *IndexingLayer { for _, il := range ils { if il.id == ilid { return il } } return nil } const multiIndexCreationFlags uint = lmdb.Create | lmdb.DupSort func (il *IndexingLayer) Init() error { if il.isInitialized { return nil } il.isInitialized = true path := filepath.Join(il.mmmm.Dir, il.name) // open lmdb env, err := lmdb.NewEnv() if err != nil { return err } env.SetMaxDBs(9) env.SetMaxReaders(1000) env.SetMapSize(1 << 38) // ~273GB // create directory if it doesn't exist and open it if err := os.MkdirAll(path, 0755); err != nil { return err } err = env.Open(path, lmdb.NoTLS, 0644) if err != nil { return err } il.lmdbEnv = env // open each db if err := il.lmdbEnv.Update(func(txn *lmdb.Txn) error { if dbi, err := txn.OpenDBI("settings", lmdb.Create); err != nil { return err } else { il.settings = dbi } if dbi, err := txn.OpenDBI("created_at", multiIndexCreationFlags); err != nil { return err } else { il.indexCreatedAt = dbi } if dbi, err := txn.OpenDBI("kind", multiIndexCreationFlags); err != nil { return err } else { il.indexKind = dbi } if dbi, err := txn.OpenDBI("pubkey", multiIndexCreationFlags); err != nil { return err } else { il.indexPubkey = dbi } if dbi, err := txn.OpenDBI("pubkeyKind", multiIndexCreationFlags); err != nil { return err } else { il.indexPubkeyKind = dbi } if dbi, err := txn.OpenDBI("tag", multiIndexCreationFlags); err != nil { return err } else { il.indexTag = dbi } if dbi, err := txn.OpenDBI("tag32", multiIndexCreationFlags); err != nil { return err } else { il.indexTag32 = dbi } if dbi, err := txn.OpenDBI("tagaddr", multiIndexCreationFlags); err != nil { return err } else { il.indexTagAddr = dbi } if dbi, err := txn.OpenDBI("ptagKind", multiIndexCreationFlags); err != nil { return err } else { il.indexPTagKind = dbi } return nil }); err != nil { return err } if err := il.migrate(); err != nil { return err } return nil } func (il *IndexingLayer) Name() string { return il.name } func (il *IndexingLayer) Close() { il.lmdbEnv.Close() }