code: func (i *smallIndex) ID(val []byte) uint32 {
  	i.mut.Lock()
  	// intentionally avoiding defer here as we want this call to be as fast as
  	// possible in the general case (folder ID already exists). The map lookup
  	// with the conversion of []byte to string is compiler optimized to not
  	// copy the []byte, which is why we don't assign it to a temp variable
  	// here.
  	if id, ok := i.val2id[string(val)]; ok {
  		i.mut.Unlock()
  		return id
  	}
  
  	id := i.nextID
  	i.nextID++
  
  	valStr := string(val)
  	i.val2id[valStr] = id
  	i.id2val[id] = valStr
  
  	key := make([]byte, len(i.prefix)+8) // prefix plus uint32 id
  	copy(key, i.prefix)
  	binary.BigEndian.PutUint32(key[len(i.prefix):], id)
  	i.db.Put(key, val, nil)
  
  	i.mut.Unlock()
  	return id
  }
docs: // ID returns the index number for the given byte slice, allocating a new one
  // and persisting this to the database if necessary.