code: func (s *LDBStore) Put(ctx context.Context, chunk Chunk) error {
  	metrics.GetOrRegisterCounter("ldbstore.put", nil).Inc(1)
  	log.Trace("ldbstore.put", "key", chunk.Address())
  
  	ikey := getIndexKey(chunk.Address())
  	var index dpaDBIndex
  
  	po := s.po(chunk.Address())
  
  	s.lock.Lock()
  
  	if s.closed {
  		s.lock.Unlock()
  		return ErrDBClosed
  	}
  	batch := s.batch
  
  	log.Trace("ldbstore.put: s.db.Get", "key", chunk.Address(), "ikey", fmt.Sprintf("%x", ikey))
  	_, err := s.db.Get(ikey)
  	if err != nil {
  		s.doPut(chunk, &index, po)
  	}
  	idata := encodeIndex(&index)
  	s.batch.Put(ikey, idata)
  
  	// add the access-chunkindex index for garbage collection
  	gcIdxKey := getGCIdxKey(&index)
  	gcIdxData := getGCIdxValue(&index, po, chunk.Address())
  	s.batch.Put(gcIdxKey, gcIdxData)
  	s.lock.Unlock()
  
  	select {
  	case s.batchesC <- struct{}{}:
  	default:
  	}
  
  	select {
  	case <-batch.c:
  		return batch.err
  	case <-ctx.Done():
  		return ctx.Err()
  	}
  }
docs: // Put adds a chunk to the database, adding indices and incrementing global counters.
  // If it already exists, it merely increments the access count of the existing entry.
  // Is thread safe