func (tb *Table) CreateSnapshotAt(dstDir string) error {
	logger.Infof("creating Table snapshot of %q...", tb.path)
	startTime := time.Now()

	var err error
	srcDir := tb.path
	srcDir, err = filepath.Abs(srcDir)
	if err != nil {
		return fmt.Errorf("cannot obtain absolute dir for %q: %s", srcDir, err)
	}
	dstDir, err = filepath.Abs(dstDir)
	if err != nil {
		return fmt.Errorf("cannot obtain absolute dir for %q: %s", dstDir, err)
	}
	if strings.HasPrefix(dstDir, srcDir+"/") {
		return fmt.Errorf("cannot create snapshot %q inside the data dir %q", dstDir, srcDir)
	}

	// Flush inmemory items to disk.
	tb.flushRawItems(true)

	// The snapshot must be created under the lock in order to prevent from
	// concurrent modifications via runTransaction.
	tb.snapshotLock.Lock()
	defer tb.snapshotLock.Unlock()

	if err := fs.MkdirAllFailIfExist(dstDir); err != nil {
		return fmt.Errorf("cannot create snapshot dir %q: %s", dstDir, err)
	}

	d, err := os.Open(srcDir)
	if err != nil {
		return fmt.Errorf("cannot open difrectory: %s", err)
	}
	defer fs.MustClose(d)

	fis, err := d.Readdir(-1)
	if err != nil {
		return fmt.Errorf("cannot read directory: %s", err)
	}
	for _, fi := range fis {
		if !fs.IsDirOrSymlink(fi) {
			// Skip non-directories.
			continue
		}
		fn := fi.Name()
		if isSpecialDir(fn) {
			// Skip special dirs.
			continue
		}
		srcPartPath := srcDir + "/" + fn
		dstPartPath := dstDir + "/" + fn
		if err := fs.HardLinkFiles(srcPartPath, dstPartPath); err != nil {
			return fmt.Errorf("cannot create hard links from %q to %q: %s", srcPartPath, dstPartPath, err)
		}
	}

	fs.SyncPath(dstDir)
	parentDir := filepath.Dir(dstDir)
	fs.SyncPath(parentDir)

	logger.Infof("created Table snapshot of %q at %q in %s", srcDir, dstDir, time.Since(startTime))
	return nil
}
// CreateSnapshotAt creates tb snapshot in the given dstDir.
//
// Snapshot is created using linux hard links, so it is usually created
// very quickly.
CreateSnapshotAt creates tb snapshot in the given dstDir.

Snapshot is created using linux hard links, so it is usually created
very quickly.
// CreateSnapshotAt creates tb snapshot in the given dstDir . // // Snapshot is created using linux hard links so it is usually created // very quickly .
func (tb *Table) CreateSnapshotAt(dstDir string) error {
	logger.Infof("creating Table snapshot of %q...", tb.path)
	startTime := time.Now()
	var err error
	srcDir := tb.path
	srcDir, err = filepath.Abs(srcDir)
	if err != nil {
		return fmt.Errorf("cannot obtain absolute dir for %q: %s", srcDir, err)
	}
	dstDir, err = filepath.Abs(dstDir)
	if err != nil {
		return fmt.Errorf("cannot obtain absolute dir for %q: %s", dstDir, err)
	}
	if strings.HasPrefix(dstDir, srcDir+"/") {
		return fmt.Errorf("cannot create snapshot %q inside the data dir %q", dstDir, srcDir)
	}
	tb.flushRawItems(true)
	tb.snapshotLock.Lock()
	defer tb.snapshotLock.Unlock()
	if err := fs.MkdirAllFailIfExist(dstDir); err != nil {
		return fmt.Errorf("cannot create snapshot dir %q: %s", dstDir, err)
	}
	d, err := os.Open(srcDir)
	if err != nil {
		return fmt.Errorf("cannot open difrectory: %s", err)
	}
	defer fs.MustClose(d)
	fis, err := d.Readdir(-1)
	if err != nil {
		return fmt.Errorf("cannot read directory: %s", err)
	}
	for _, fi := range fis {
		if !fs.IsDirOrSymlink(fi) {
			continue
		}
		fn := fi.Name()
		if isSpecialDir(fn) {
			continue
		}
		srcPartPath := srcDir + "/" + fn
		dstPartPath := dstDir + "/" + fn
		if err := fs.HardLinkFiles(srcPartPath, dstPartPath); err != nil {
			return fmt.Errorf("cannot create hard links from %q to %q: %s", srcPartPath, dstPartPath, err)
		}
	}
	fs.SyncPath(dstDir)
	parentDir := filepath.Dir(dstDir)
	fs.SyncPath(parentDir)
	logger.Infof("created Table snapshot of %q at %q in %s", srcDir, dstDir, time.Since(startTime))
	return nil
}
func ( tb * Table ) CreateSnapshotAt ( dstDir string ) error { logger . Infof ( " " , tb . path ) startTime := time . Now ( ) var err error srcDir := tb . path srcDir , err = filepath . Abs ( srcDir ) if err != nil { return fmt . Errorf ( " " , srcDir , err ) } dstDir , err = filepath . Abs ( dstDir ) if err != nil { return fmt . Errorf ( " " , dstDir , err ) } if strings . HasPrefix ( dstDir , srcDir + " " ) { return fmt . Errorf ( " " , dstDir , srcDir ) } tb . flushRawItems ( true ) tb . snapshotLock . Lock ( ) defer tb . snapshotLock . Unlock ( ) if err := fs . MkdirAllFailIfExist ( dstDir ) ; err != nil { return fmt . Errorf ( " " , dstDir , err ) } d , err := os . Open ( srcDir ) if err != nil { return fmt . Errorf ( " " , err ) } defer fs . MustClose ( d ) fis , err := d . Readdir ( - 1 ) if err != nil { return fmt . Errorf ( " " , err ) } for _ , fi := range fis { if ! fs . IsDirOrSymlink ( fi ) { continue } fn := fi . Name ( ) if isSpecialDir ( fn ) { continue } srcPartPath := srcDir + " " + fn dstPartPath := dstDir + " " + fn if err := fs . HardLinkFiles ( srcPartPath , dstPartPath ) ; err != nil { return fmt . Errorf ( " " , srcPartPath , dstPartPath , err ) } } fs . SyncPath ( dstDir ) parentDir := filepath . Dir ( dstDir ) fs . SyncPath ( parentDir ) logger . Infof ( " " , srcDir , dstDir , time . Since ( startTime ) ) return nil }
CreateSnapshotAt creates tb snapshot in the given dstDir.
CreateSnapshotAt creates tb snapshot in the given dstDir .
// Flush inmemory items to disk. // The snapshot must be created under the lock in order to prevent from // concurrent modifications via runTransaction. // Skip non-directories. // Skip special dirs.