// Truncate truncates or extends the given file to the given size.
// May block if there is too much unflushed data; in that case, it
// will be unblocked by a future sync.
555679
func (fbo *folderBlockOps) Truncate(
	ctx context.Context, lState *kbfssync.LockState,
	kmd KeyMetadataWithRootDirEntry, file Node, size uint64) error {
	// If there is too much unflushed data, we should wait until some
	// of it gets flush so our memory usage doesn't grow without
	// bound.
	//
	// Assume the whole remaining file will be dirty after this
	// truncate.  TODO: try to figure out how many bytes actually will
	// be dirtied ahead of time?
	c, err := fbo.config.DirtyBlockCache().RequestPermissionToDirty(ctx,
		fbo.id(), int64(size))
	if err != nil {
		return err
	}
	defer fbo.config.DirtyBlockCache().UpdateUnsyncedBytes(fbo.id(),
		-int64(size), false)
	err = fbo.maybeWaitOnDeferredWrites(ctx, lState, file, c)
	if err != nil {
		return err
	}

	fbo.blockLock.Lock(lState)
	defer fbo.blockLock.Unlock(lState)

	filePath, err := fbo.pathFromNodeForBlockWriteLocked(lState, file)
	if err != nil {
		return err
	}

	defer func() {
		fbo.doDeferWrite = false
	}()

	latestWrite, dirtyPtrs, newlyDirtiedChildBytes, err := fbo.truncateLocked(
		ctx, lState, kmd, filePath, size)
	if err != nil {
		return err
	}

	if latestWrite != nil {
		fbo.observers.localChange(ctx, file, *latestWrite)
	}

	if fbo.doDeferWrite {
		// There's an ongoing sync, and this truncate altered
		// dirty blocks that are in the process of syncing.  So,
		// we have to redo this truncate once the sync is complete,
		// using the new file path.
		fbo.vlog.CLogf(
			ctx, libkb.VLog1, "Deferring a truncate to file %v",
			filePath.TailPointer())
		ds := fbo.deferred[filePath.TailRef()]
		ds.dirtyDeletes = append(ds.dirtyDeletes, dirtyPtrs...)
		ds.writes = append(ds.writes,
			func(ctx context.Context, lState *kbfssync.LockState,
				kmd KeyMetadataWithRootDirEntry, f data.Path) error {
				// We are about to re-dirty these bytes, so mark that
				// they will no longer be synced via the old file.
				df := fbo.getOrCreateDirtyFileLocked(lState, filePath)
				df.UpdateNotYetSyncingBytes(-newlyDirtiedChildBytes)

				// Truncate the file again.  We know this won't be
				// deferred, so no need to check the new ptrs.
				_, _, _, err := fbo.truncateLocked(
					ctx, lState, kmd, f, size)
				return err
			})
		ds.waitBytes += newlyDirtiedChildBytes
		fbo.deferred[filePath.TailRef()] = ds
	}

	return nil
}
7054
func (c *Connector) TruncateScope(ctx context.Context, scope string) error {
	return nil
}
148137
func (s *ListKeyPoliciesOutput) SetTruncated(v bool) *ListKeyPoliciesOutput {
	s.Truncated = &v
	return s
}
105751
func (s *SeriesCollection) Truncate(length int) {
	ulength := uint(length)
	if ulength < uint(len(s.Points)) {
		s.Points = s.Points[:ulength]
	}
	if ulength < uint(len(s.Keys)) {
		s.Keys = s.Keys[:ulength]
	}
	if ulength < uint(len(s.SeriesKeys)) {
		s.SeriesKeys = s.SeriesKeys[:ulength]
	}
	if ulength < uint(len(s.Names)) {
		s.Names = s.Names[:ulength]
	}
	if ulength < uint(len(s.Tags)) {
		s.Tags = s.Tags[:ulength]
	}
	if ulength < uint(len(s.Types)) {
		s.Types = s.Types[:ulength]
	}
	if ulength < uint(len(s.SeriesIDs)) {
		s.SeriesIDs = s.SeriesIDs[:ulength]
	}
}
622388
func (c *adminClient) TruncateScope(ctx context.Context, s string) error {
	return c.connector.TruncateScope(ctx, s)
}
756492
func Truncate(str string, length int, ending string) string {
	var aftstr, befstr string
	if len(str) > length {
		words := strings.Fields(str)
		before, present := 0, 0
		for i := range words {
			befstr = aftstr
			before = present
			aftstr = aftstr + words[i] + " "
			present = len(aftstr)
			if present > length && i != 0 {
				if (length - before) < (present - length) {
					return Trim(befstr, " /\\.,\"'#!?&@+-") + ending
				}
				return Trim(aftstr, " /\\.,\"'#!?&@+-") + ending
			}
		}
	}

	return str
}
1343263
func (file *File) Close() (err error) {
	defer func() {
		if err != nil {
			os.Remove(file.tmpfile.Name())
			file.aborted = true
		}
	}()

	if file.closed {
		err = errors.New("close on closed file")
		return
	}
	if file.aborted {
		err = errors.New("close on aborted file")
		return
	}

	if err = file.tmpfile.Close(); err != nil {
		return
	}

	err = os.Rename(file.tmpfile.Name(), file.name)

	file.closed = true
	return
}
814026
func (r *RLockedFile) Close() (err error) {
	r.mutex.Lock()
	defer r.mutex.Unlock()

	if r.refs == 0 {
		return os.ErrInvalid
	}

	r.refs--
	if r.refs == 0 {
		err = r.File.Close()
	}

	return err
}
932948
func TruncateString(str string, limit int) string {
	if len(str) < limit {
		return str
	}
	return str[:limit]
}
1352097
func (f *removeOnClose) Close() error {
	if f == nil || f.File == nil {
		return nil
	}
	name := f.File.Name()
	if err := f.File.Close(); err != nil {
		return err
	}
	if err := os.Remove(name); err != nil && !os.IsNotExist(err) {
		return err
	}
	return nil
}
556376
func (c *Condition) Truncate(s string, w int, tail string) string {
	if c.StringWidth(s) <= w {
		return s
	}
	r := []rune(s)
	tw := c.StringWidth(tail)
	w -= tw
	width := 0
	i := 0
	for ; i < len(r); i++ {
		cw := c.RuneWidth(r[i])
		if width+cw > w {
			break
		}
		width += cw
	}
	return string(r[0:i]) + tail
}
347695
func truncateWithLength(source string, length int) string {
	if len(source) < length {
		return source
	}
	return source[:length]
}
534957
func (w WriteRange) End() uint64 {
	if w.isTruncate() {
		panic("Truncates don't have an end")
	}
	return w.Off + w.Len
}
1070129
func (stack *Stack) TruncateToSize(newsize int) {
	el := make([]StackElem, newsize)
	copy(el, stack.elements)
	stack.elements = el
	stack.tos = newsize - 1
}
87266
func (s *PendingTaskCount) SetTruncated(v bool) *PendingTaskCount {
	s.Truncated = &v
	return s
}
14553
func (c Context) Truncate(input string, length int) string {
	if length < 0 && len(input)+length > 0 {
		return input[len(input)+length:]
	}
	if length >= 0 && len(input) > length {
		return input[:length]
	}
	return input
}
297841
func TruncateToRowKeyLen(key kv.Key) kv.Key {
	if len(key) > recordRowKeyLen {
		return key[:recordRowKeyLen]
	}
	return key
}