func (s *BoltStore) removeFromRootLabel(tx *bolt.Tx, itemType string, itemID uint64, userid []byte) { index := tx.Bucket(boltBucketLabelRootIndex) id := index.Get(userid) if id != nil { label := itemType + "/" + strconv.FormatUint(itemID, 10) b := tx.Bucket(boltBucketLabels) v := b.Get(id) root := &Label{} root.UnmarshalMsg(v) if strings.Contains(root.Content, ","+label) { root.Content = strings.Replace(root.Content, ","+label, "", 1) } else if strings.HasPrefix(root.Content, label+",") { root.Content = strings.Replace(root.Content, label+",", "", 1) } else { root.Content = strings.Replace(root.Content, label, "", 1) } v, err := root.MarshalMsg(nil) if err != nil { return } b.Put(id, v) } }
// Inserts a key into the database. func simulatePutHandler(tx *bolt.Tx, qdb *QuickDB) { var err error keys, value := randKeys(), randValue() // Retrieve root bucket. b := tx.Bucket(keys[0]) if b == nil { b, err = tx.CreateBucket(keys[0]) if err != nil { panic("create bucket: " + err.Error()) } } // Create nested buckets, if necessary. for _, key := range keys[1 : len(keys)-1] { child := b.Bucket(key) if child != nil { b = child } else { b, err = b.CreateBucket(key) if err != nil { panic("create bucket: " + err.Error()) } } } // Insert into database. if err := b.Put(keys[len(keys)-1], value); err != nil { panic("put: " + err.Error()) } // Insert into in-memory database. qdb.Put(keys, value) }
// Retrieves a key from the database and verifies that it is what is expected. func simulateGetHandler(tx *bolt.Tx, qdb *QuickDB) { // Randomly retrieve an existing exist. keys := qdb.Rand() if len(keys) == 0 { return } // Retrieve root bucket. b := tx.Bucket(keys[0]) if b == nil { panic(fmt.Sprintf("bucket[0] expected: %08x\n", trunc(keys[0], 4))) } // Drill into nested buckets. for _, key := range keys[1 : len(keys)-1] { b = b.Bucket(key) if b == nil { panic(fmt.Sprintf("bucket[n] expected: %v -> %v\n", keys, key)) } } // Verify key/value on the final bucket. expected := qdb.Get(keys) actual := b.Get(keys[len(keys)-1]) if !bytes.Equal(actual, expected) { fmt.Println("=== EXPECTED ===") fmt.Println(expected) fmt.Println("=== ACTUAL ===") fmt.Println(actual) fmt.Println("=== END ===") panic("value mismatch") } }
func (s *BoltStore) getLabel(tx *bolt.Tx, id []byte) *Label { b := tx.Bucket(boltBucketLabels) v := b.Get(id) if v != nil { label := &Label{} label.UnmarshalMsg(v) return label } return nil }
func (s *BoltStore) addEvent(tx *bolt.Tx, event *Event, userid uint64) error { b := tx.Bucket(boltBucketEvents) eventID, err := b.NextSequence() if err != nil { return err } v, err := event.MarshalMsg(nil) if err != nil { return err } id := make([]byte, 24) binary.BigEndian.PutUint64(id[:8], userid) binary.BigEndian.PutUint64(id[8:16], event.ClientTS) binary.BigEndian.PutUint64(id[16:], eventID) return b.Put(id, v) }
func (s *BoltStore) saveEpisode(tx *bolt.Tx, ep *Episode) error { index := tx.Bucket(boltBucketEpisodeGUIDIndex) guid := []byte(ep.GUID) if index.Get(guid) != nil { return nil } var err error b := tx.Bucket(boltBucketEpisodes) ep.ID, err = b.NextSequence() if err != nil { return err } ep.EncodeFeed() v, err := ep.MarshalMsg(nil) if err != nil { return err } id := uint64Bytes(ep.ID) err = index.Put(guid, id) if err != nil { return err } idxID := make([]byte, 16) binary.BigEndian.PutUint64(idxID[:8], ep.CastID) binary.BigEndian.PutUint64(idxID[8:], ep.ID) castIndex := tx.Bucket(boltBucketEpisodeCastIDIndex) err = castIndex.Put(idxID, id) if err != nil { return err } crawlTSIndex := tx.Bucket(boltBucketEpisodeCrawlTSIndex) idxID = make([]byte, 24) binary.BigEndian.PutUint64(idxID[:8], uint64(ep.CrawlTS)) binary.BigEndian.PutUint64(idxID[8:16], ep.ID) binary.BigEndian.PutUint64(idxID[16:], ep.CastID) err = crawlTSIndex.Put(idxID, id) if err != nil { return err } return b.Put(id, v) }
func (s *BoltStore) addToRootLabel(tx *bolt.Tx, itemType string, itemID uint64, userid []byte) { var err error label := itemType + "/" + strconv.FormatUint(itemID, 10) b := tx.Bucket(boltBucketLabels) index := tx.Bucket(boltBucketLabelRootIndex) id := index.Get(userid) if id != nil { v := b.Get(id) root := &Label{} root.UnmarshalMsg(v) if strings.Contains(root.Content, label) { return } if root.Content != "" { root.Content += "," } root.Content += label v, err = root.MarshalMsg(nil) if err != nil { return } b.Put(id, v) } else { root := &Label{ Name: "root", Content: itemType + "/" + strconv.FormatUint(itemID, 10), Root: true, } root.ID, err = b.NextSequence() if err != nil { return } v, err := root.MarshalMsg(nil) if err != nil { return } id = uint64Bytes(root.ID) index.Put(userid, id) idxID := []byte{} idxID = append(idxID, userid...) idxID = append(idxID, id...) index = tx.Bucket(boltBucketLabelUserIDIndex) err = index.Put(idxID, id) if err != nil { return } b.Put(id, v) } }