/// General version for 2 or 3-D objects const Field3D VDDX(const Field &v, const Field &f, CELL_LOC outloc, DIFF_METHOD method) { upwind_func func = fVDDX; DiffLookup *table = UpwindTable; CELL_LOC vloc = v.getLocation(); CELL_LOC inloc = f.getLocation(); // Input location CELL_LOC diffloc = inloc; // Location of differential result if(StaggerGrids && (outloc == CELL_DEFAULT)) { // Take care of CELL_DEFAULT case outloc = diffloc; // No shift (i.e. same as no stagger case) } if(StaggerGrids && (vloc != inloc)) { // Staggered grids enabled, and velocity at different location to value if(vloc == CELL_XLOW) { // V staggered w.r.t. variable func = sfVDDX; table = UpwindStagTable; diffloc = CELL_CENTRE; } else if((vloc == CELL_CENTRE) && (inloc == CELL_XLOW)) { // Shifted func = sfVDDX; table = UpwindStagTable; diffloc = CELL_XLOW; } else { // More complicated. Deciding what to do here isn't straightforward // For now, interpolate velocity to the same location as f. // Should be able to do something like: //return VDDX(interp_to(v, inloc), f, outloc, method); // Instead, pretend it's been shifted FIX THIS diffloc = vloc; } } if(method != DIFF_DEFAULT) { // Lookup function func = lookupUpwindFunc(table, method); } /// Clone inputs (for shifting) Field *vp = v.clone(); Field *fp = f.clone(); if(ShiftXderivs && (ShiftOrder == 0)) { // Shift in Z using FFT if needed vp->ShiftToReal(true); fp->ShiftToReal(true); } Field3D result; result.Allocate(); // Make sure data allocated real ***d = result.getData(); bindex bx; stencil vval, fval; start_index(&bx); do { vp->SetXStencil(vval, bx, diffloc); fp->SetXStencil(fval, bx); // Location is always the same as input d[bx.jx][bx.jy][bx.jz] = func(vval, fval) / dx[bx.jx][bx.jy]; } while(next_index3(&bx)); if(ShiftXderivs && (ShiftOrder == 0)) result = result.ShiftZ(false); // Shift back result.setLocation(inloc); #ifdef CHECK // Mark boundaries as invalid result.bndry_xin = result.bndry_xout = result.bndry_yup = result.bndry_ydown = false; #endif // Delete clones delete vp; delete fp; return interp_to(result, outloc); }
/* * doing similar to $ gtar | compression | encryption */ static void start_backup( dle_t *dle, char *host, int dataf, int mesgf, int indexf) { char tmppath[PATH_MAX]; int dumpin, dumpout, compout; char *cmd = NULL; char *indexcmd = NULL; char *dirname = NULL; int l; char dumptimestr[80] = "UNUSED"; struct tm *gmtm; amandates_t *amdates = NULL; time_t prev_dumptime = 0; char *error_pn = NULL; char *compopt = NULL; char *encryptopt = skip_argument; char *tquoted; char *fquoted; char *qdisk; int infd, outfd; ssize_t nb; char buf[32768]; char *amandates_file = NULL; am_level_t *alevel = (am_level_t *)dle->levellist->data; int level = alevel->level; error_pn = g_strconcat(get_pname(), "-smbclient", NULL); qdisk = quote_string(dle->disk); dbprintf(_("start: %s:%s lev %d\n"), host, qdisk, level); g_fprintf(stderr, _("%s: start [%s:%s level %d]\n"), get_pname(), host, qdisk, level); /* apply client-side encryption here */ if ( dle->encrypt == ENCRYPT_CUST ) { encpid = pipespawn(dle->clnt_encrypt, STDIN_PIPE, 0, &compout, &dataf, &mesgf, dle->clnt_encrypt, encryptopt, NULL); dbprintf(_("gnutar: pid %ld: %s\n"), (long)encpid, dle->clnt_encrypt); } else { compout = dataf; encpid = -1; } /* now do the client-side compression */ if(dle->compress == COMP_FAST || dle->compress == COMP_BEST) { compopt = skip_argument; #if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT) if(dle->compress == COMP_BEST) { compopt = COMPRESS_BEST_OPT; } else { compopt = COMPRESS_FAST_OPT; } #endif comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE, 0, &dumpout, &compout, &mesgf, COMPRESS_PATH, compopt, NULL); dbprintf(_("gnutar: pid %ld: %s"), (long)comppid, COMPRESS_PATH); if(compopt != skip_argument) { dbprintf(_("pid %ld: %s %s\n"), (long)comppid, COMPRESS_PATH, compopt); } else { dbprintf(_("pid %ld: %s\n"), (long)comppid, COMPRESS_PATH); } } else if (dle->compress == COMP_CUST) { compopt = skip_argument; comppid = pipespawn(dle->compprog, STDIN_PIPE, 0, &dumpout, &compout, &mesgf, dle->compprog, compopt, NULL); if(compopt != skip_argument) { dbprintf(_("pid %ld: %s %s\n"), (long)comppid, dle->compprog, compopt); } else { dbprintf(_("pid %ld: %s\n"), (long)comppid, dle->compprog); } } else { dumpout = compout; comppid = -1; } gnutar_list_dir = getconf_str(CNF_GNUTAR_LIST_DIR); if (strlen(gnutar_list_dir) == 0) gnutar_list_dir = NULL; #ifdef SAMBA_CLIENT /* { */ if (dle->device[0] == '/' && dle->device[1]=='/') amfree(incrname); else #endif /* } */ if (gnutar_list_dir) { char *basename = NULL; char number[NUM_STR_SIZE]; char *inputname = NULL; int baselevel; char *sdisk = sanitise_filename(dle->disk); basename = g_strjoin(NULL, gnutar_list_dir, "/", host, sdisk, NULL); amfree(sdisk); g_snprintf(number, sizeof(number), "%d", level); incrname = g_strjoin(NULL, basename, "_", number, ".new", NULL); unlink(incrname); /* * Open the listed incremental file from the previous level. Search * backward until one is found. If none are found (which will also * be true for a level 0), arrange to read from /dev/null. */ baselevel = level; infd = -1; while (infd == -1) { if (--baselevel >= 0) { g_snprintf(number, sizeof(number), "%d", baselevel); g_free(inputname); inputname = g_strconcat(basename, "_", number, NULL); } else { g_free(inputname); inputname = g_strdup("/dev/null"); } if ((infd = open(inputname, O_RDONLY)) == -1) { int save_errno = errno; char *qname = quote_string(inputname); dbprintf(_("gnutar: error opening '%s': %s\n"), qname, strerror(save_errno)); if (baselevel < 0) { error(_("error [opening '%s': %s]"), qname, strerror(save_errno)); /*NOTREACHED*/ } amfree(qname); } } /* * Copy the previous listed incremental file to the new one. */ if ((outfd = open(incrname, O_WRONLY|O_CREAT, 0600)) == -1) { error(_("error [opening '%s': %s]"), incrname, strerror(errno)); /*NOTREACHED*/ } while ((nb = read(infd, &buf, sizeof(buf))) > 0) { if (full_write(outfd, &buf, (size_t)nb) < (size_t)nb) { error(_("error [writing to '%s': %s]"), incrname, strerror(errno)); /*NOTREACHED*/ } } if (nb < 0) { error(_("error [reading from '%s': %s]"), inputname, strerror(errno)); /*NOTREACHED*/ } if (close(infd) != 0) { error(_("error [closing '%s': %s]"), inputname, strerror(errno)); /*NOTREACHED*/ } if (close(outfd) != 0) { error(_("error [closing '%s': %s]"), incrname, strerror(errno)); /*NOTREACHED*/ } tquoted = quote_string(incrname); if(baselevel >= 0) { fquoted = quote_string(inputname); dbprintf(_("doing level %d dump as listed-incremental from '%s' to '%s'\n"), level, fquoted, tquoted); amfree(fquoted); } else { dbprintf(_("doing level %d dump as listed-incremental to '%s'\n"), level, tquoted); } amfree(tquoted); amfree(inputname); amfree(basename); } else { /* no gnutar-listdir, so we're using amandates */ /* find previous dump time, failing completely if there's a problem */ amandates_file = getconf_str(CNF_AMANDATES); if(!start_amandates(amandates_file, 0)) { error(_("error [opening %s: %s]"), amandates_file, strerror(errno)); /*NOTREACHED*/ } amdates = amandates_lookup(dle->disk); prev_dumptime = EPOCH; for(l = 0; l < level; l++) { if(amdates->dates[l] > prev_dumptime) prev_dumptime = amdates->dates[l]; } finish_amandates(); free_amandates(); gmtm = gmtime(&prev_dumptime); g_snprintf(dumptimestr, sizeof(dumptimestr), "%04d-%02d-%02d %2d:%02d:%02d GMT", gmtm->tm_year + 1900, gmtm->tm_mon+1, gmtm->tm_mday, gmtm->tm_hour, gmtm->tm_min, gmtm->tm_sec); dbprintf(_("gnutar: doing level %d dump from amandates-derived date: %s\n"), level, dumptimestr); } dirname = amname_to_dirname(dle->device); cur_dumptime = time(0); cur_level = level; cur_disk = g_strdup(dle->disk); #ifdef GNUTAR # define PROGRAM_GNUTAR GNUTAR #else # define PROGRAM_GNUTAR "tar" #endif indexcmd = g_strjoin(NULL, PROGRAM_GNUTAR, " -tf", " -", " 2>/dev/null", " | sed", " -e", " \'s/^\\.//\'", NULL); #ifdef SAMBA_CLIENT /* { */ /* Use sambatar if the disk to back up is a PC disk */ if (dle->device[0] == '/' && dle->device[1]=='/') { char *sharename = NULL, *user_and_password = NULL, *domain = NULL; char *share = NULL, *subdir = NULL; char *pwtext = NULL; char *taropt; int passwdf = -1; size_t lpass; size_t pwtext_len; char *pw_fd_env; parsesharename(dle->device, &share, &subdir); if (!share) { amfree(share); amfree(subdir); set_pname(error_pn); amfree(error_pn); error(_("cannot parse disk entry %s for share/subdir"), qdisk); /*NOTREACHED*/ } if ((subdir) && (SAMBA_VERSION < 2)) { amfree(share); amfree(subdir); set_pname(error_pn); amfree(error_pn); error(_("subdirectory specified for share %s but samba not v2 or better"), qdisk); /*NOTREACHED*/ } if ((user_and_password = findpass(share, &domain)) == NULL) { if(domain) { memset(domain, '\0', strlen(domain)); amfree(domain); } set_pname(error_pn); amfree(error_pn); error(_("error [invalid samba host or password not found?]")); /*NOTREACHED*/ } lpass = strlen(user_and_password); if ((pwtext = strchr(user_and_password, '%')) == NULL) { memset(user_and_password, '\0', lpass); amfree(user_and_password); if(domain) { memset(domain, '\0', strlen(domain)); amfree(domain); } set_pname(error_pn); amfree(error_pn); error(_("password field not \'user%%pass\' for %s"), qdisk); /*NOTREACHED*/ } *pwtext++ = '\0'; pwtext_len = strlen(pwtext); if ((sharename = makesharename(share, 0)) == 0) { memset(user_and_password, '\0', lpass); amfree(user_and_password); if(domain) { memset(domain, '\0', strlen(domain)); amfree(domain); } set_pname(error_pn); amfree(error_pn); error(_("error [can't make share name of %s]"), share); /*NOTREACHED*/ } taropt = g_strdup("-T"); if(dle->exclude_file && dle->exclude_file->nb_element == 1) { strappend(taropt, "X"); } #if SAMBA_VERSION >= 2 strappend(taropt, "q"); #endif strappend(taropt, "c"); if (level != 0) { strappend(taropt, "g"); } else if (dle->record) { strappend(taropt, "a"); } if (subdir) { dbprintf(_("gnutar: backup of %s/%s\n"), sharename, subdir); } else { dbprintf(_("gnutar: backup of %s\n"), sharename); } program->backup_name = program->restore_name = SAMBA_CLIENT; cmd = g_strdup(program->backup_name); info_tapeheader(dle); start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd); if (pwtext_len > 0) { pw_fd_env = "PASSWD_FD"; } else { pw_fd_env = "dummy_PASSWD_FD"; } dumppid = pipespawn(cmd, STDIN_PIPE|PASSWD_PIPE, 0, &dumpin, &dumpout, &mesgf, pw_fd_env, &passwdf, "smbclient", sharename, *user_and_password ? "-U" : skip_argument, *user_and_password ? user_and_password : skip_argument, "-E", domain ? "-W" : skip_argument, domain ? domain : skip_argument, #if SAMBA_VERSION >= 2 subdir ? "-D" : skip_argument, subdir ? subdir : skip_argument, #endif "-d0", taropt, "-", dle->exclude_file && dle->exclude_file->nb_element == 1 ? dle->exclude_file->first->name : skip_argument, NULL); if(domain) { memset(domain, '\0', strlen(domain)); amfree(domain); } if(pwtext_len > 0 && full_write(passwdf, pwtext, pwtext_len) < pwtext_len) { int save_errno = errno; aclose(passwdf); memset(user_and_password, '\0', lpass); amfree(user_and_password); set_pname(error_pn); amfree(error_pn); error(_("error [password write failed: %s]"), strerror(save_errno)); /*NOTREACHED*/ } memset(user_and_password, '\0', lpass); amfree(user_and_password); aclose(passwdf); amfree(sharename); amfree(share); amfree(subdir); amfree(taropt); tarpid = dumppid; } else #endif /*end of samba */ { int nb_exclude = 0; int nb_include = 0; GPtrArray *argv_ptr = g_ptr_array_new(); char *file_exclude = NULL; char *file_include = NULL; if (dle->exclude_file) nb_exclude+=dle->exclude_file->nb_element; if (dle->exclude_list) nb_exclude+=dle->exclude_list->nb_element; if (dle->include_file) nb_include+=dle->include_file->nb_element; if (dle->include_list) nb_include+=dle->include_list->nb_element; if (nb_exclude > 0) file_exclude = build_exclude(dle, 0); if (nb_include > 0) file_include = build_include(dle, 0); cmd = g_strjoin(NULL, amlibexecdir, "/", "runtar", NULL); info_tapeheader(dle); start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd); g_ptr_array_add(argv_ptr, g_strdup("runtar")); if (g_options->config) g_ptr_array_add(argv_ptr, g_strdup(g_options->config)); else g_ptr_array_add(argv_ptr, g_strdup("NOCONFIG")); #ifdef GNUTAR g_ptr_array_add(argv_ptr, g_strdup(GNUTAR)); #else g_ptr_array_add(argv_ptr, g_strdup("tar")); #endif g_ptr_array_add(argv_ptr, g_strdup("--create")); g_ptr_array_add(argv_ptr, g_strdup("--file")); g_ptr_array_add(argv_ptr, g_strdup("-")); g_ptr_array_add(argv_ptr, g_strdup("--directory")); canonicalize_pathname(dirname, tmppath); g_ptr_array_add(argv_ptr, g_strdup(tmppath)); g_ptr_array_add(argv_ptr, g_strdup("--one-file-system")); if (gnutar_list_dir && incrname) { g_ptr_array_add(argv_ptr, g_strdup("--listed-incremental")); g_ptr_array_add(argv_ptr, g_strdup(incrname)); } else { g_ptr_array_add(argv_ptr, g_strdup("--incremental")); g_ptr_array_add(argv_ptr, g_strdup("--newer")); g_ptr_array_add(argv_ptr, g_strdup(dumptimestr)); } #ifdef ENABLE_GNUTAR_ATIME_PRESERVE /* --atime-preserve causes gnutar to call * utime() after reading files in order to * adjust their atime. However, utime() * updates the file's ctime, so incremental * dumps will think the file has changed. */ g_ptr_array_add(argv_ptr, g_strdup("--atime-preserve")); #endif g_ptr_array_add(argv_ptr, g_strdup("--sparse")); g_ptr_array_add(argv_ptr, g_strdup("--ignore-failed-read")); g_ptr_array_add(argv_ptr, g_strdup("--totals")); if(file_exclude) { g_ptr_array_add(argv_ptr, g_strdup("--exclude-from")); g_ptr_array_add(argv_ptr, g_strdup(file_exclude)); } if(file_include) { g_ptr_array_add(argv_ptr, g_strdup("--files-from")); g_ptr_array_add(argv_ptr, g_strdup(file_include)); } else { g_ptr_array_add(argv_ptr, g_strdup(".")); } g_ptr_array_add(argv_ptr, NULL); dumppid = pipespawnv(cmd, STDIN_PIPE, 0, &dumpin, &dumpout, &mesgf, (char **)argv_ptr->pdata); tarpid = dumppid; amfree(file_exclude); amfree(file_include); g_ptr_array_free_full(argv_ptr); } dbprintf(_("gnutar: %s: pid %ld\n"), cmd, (long)dumppid); amfree(qdisk); amfree(dirname); amfree(cmd); amfree(indexcmd); amfree(error_pn); /* close the write ends of the pipes */ aclose(dumpin); aclose(dumpout); //aclose(compout); aclose(dataf); aclose(mesgf); if (dle->create_index) aclose(indexf); }
int end_index() const { return start_index() + _header_queue.size(); }
static void start_backup( dle_t *dle, char *host, int dataf, int mesgf, int indexf) { int dumpin, dumpout, compout; char *dumpkeys = NULL; char *device = NULL; char *fstype = NULL; char *cmd = NULL; char *cmdX = NULL; char *indexcmd = NULL; char level_str[NUM_STR_SIZE]; char *compopt = NULL; char *encryptopt = skip_argument; char *qdisk; char *config; am_level_t *alevel = (am_level_t *)dle->levellist->data; int level = alevel->level; g_snprintf(level_str, sizeof(level_str), "%d", level); qdisk = quote_string(dle->disk); dbprintf(_("start: %s:%s lev %d\n"), host, qdisk, level); g_fprintf(stderr, _("%s: start [%s:%s level %d]\n"), get_pname(), host, qdisk, level); amfree(qdisk); /* apply client-side encryption here */ if (dle->encrypt == ENCRYPT_CUST ) { encpid = pipespawn(dle->clnt_encrypt, STDIN_PIPE, 0, &compout, &dataf, &mesgf, dle->clnt_encrypt, encryptopt, NULL); dbprintf(_("gnutar: pid %ld: %s\n"), (long)encpid, dle->clnt_encrypt); } else { compout = dataf; encpid = -1; } /* now do the client-side compression */ if(dle->compress == COMP_FAST || dle->compress == COMP_BEST) { compopt = skip_argument; #if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT) if(dle->compress == COMP_BEST) { compopt = COMPRESS_BEST_OPT; } else { compopt = COMPRESS_FAST_OPT; } #endif comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE, 0, &dumpout, &compout, &mesgf, COMPRESS_PATH, compopt, NULL); dbprintf(_("dump: pid %ld: %s"), (long)comppid, COMPRESS_PATH); if(compopt != skip_argument) { dbprintf(" %s", compopt); } dbprintf("\n"); } else if (dle->compress == COMP_CUST) { compopt = skip_argument; comppid = pipespawn(dle->compprog, STDIN_PIPE, 0, &dumpout, &compout, &mesgf, dle->compprog, compopt, NULL); dbprintf(_("gnutar-cust: pid %ld: %s"), (long)comppid, dle->compprog); if(compopt != skip_argument) { dbprintf(" %s", compopt); } dbprintf("\n"); } else { dumpout = compout; comppid = -1; } /* invoke dump */ device = amname_to_devname(dle->device); fstype = amname_to_fstype(dle->device); dbprintf(_("dumping device '%s' with '%s'\n"), device, fstype); #if defined(USE_RUNDUMP) || !defined(DUMP) cmd = g_strjoin(NULL, amlibexecdir, "/", "rundump", NULL); cmdX = cmd; if (g_options->config) config = g_options->config; else config = "NOCONFIG"; #else cmd = g_strdup(DUMP); cmdX = skip_argument; config = skip_argument; #endif #ifndef AIX_BACKUP /* { */ /* normal dump */ #ifdef XFSDUMP /* { */ #ifdef DUMP /* { */ if (g_str_equal(amname_to_fstype(dle->device), "xfs")) #else /* } { */ if (1) #endif /* } */ { char *progname; g_free(cmd); progname = cmd = g_strconcat(amlibexecdir, "/", "rundump", NULL); cmdX = cmd; if (g_options->config) config = g_options->config; else config = "NOCONFIG"; program->backup_name = XFSDUMP; program->restore_name = XFSRESTORE; indexcmd = g_strjoin(NULL, XFSRESTORE, " -t", " -v", " silent", " -", " 2>/dev/null", " | sed", " -e", " \'s/^/\\//\'", NULL); info_tapeheader(dle); start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd); dumpkeys = g_strdup(level_str); dumppid = pipespawn(progname, STDIN_PIPE, 0, &dumpin, &dumpout, &mesgf, cmdX, config, "xfsdump", !dle->record ? "-J" : skip_argument, "-F", "-l", dumpkeys, "-", device, NULL); } else #endif /* } */ #ifdef VXDUMP /* { */ #ifdef DUMP if (g_str_equal(amname_to_fstype(dle->device), "vxfs")) #else if (1) #endif { char *progname; #ifdef USE_RUNDUMP g_free(cmd); progname = cmd = g_strconcat(amlibexecdir, "/", "rundump", NULL); cmdX = cmd; if (g_options->config) config = g_options->config; else config = "NOCONFIG"; #else char *progname; g_free(cmd); progname = cmd = g_strdup(VXDUMP); cmdX = skip_argument; config = skip_argument; #endif program->backup_name = VXDUMP; program->restore_name = VXRESTORE; dumpkeys = g_strjoin(NULL, level_str, !dle->record ? "" : "u", "s", "f", NULL); indexcmd = g_strjoin(NULL, VXRESTORE, " -tvf", " -", " 2>/dev/null", " | ", LEAF_AND_DIRS, NULL); info_tapeheader(dle); start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd); dumppid = pipespawn(progname, STDIN_PIPE, 0, &dumpin, &dumpout, &mesgf, cmdX, config, "vxdump", dumpkeys, "1048576", "-", device, NULL); } else #endif /* } */ #ifdef VDUMP /* { */ #ifdef DUMP if (g_str_equal(amname_to_fstype(dle->device), "advfs")) #else if (1) #endif { g_free(cmd); cmd = g_strconcat(amlibexecdir, "/", "rundump", NULL); cmdX = cmd; if (g_options->config) config = g_options->config; else config = "NOCONFIG"; g_free(device); device = g_strdup(amname_to_dirname(dle->device)); program->backup_name = VDUMP; program->restore_name = VRESTORE; dumpkeys = g_strjoin(NULL, level_str, !dle->record ? "" : "u", "b", "f", NULL); indexcmd = g_strjoin(NULL, VRESTORE, " -tvf", " -", " 2>/dev/null", " | ", "sed -e \'\n/^\\./ {\ns/^\\.//\ns/, [0-9]*$//\ns/^\\.//\ns/ @-> .*$//\nt\n}\nd\n\'", NULL); info_tapeheader(dle); start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd); dumppid = pipespawn(cmd, STDIN_PIPE, 0, &dumpin, &dumpout, &mesgf, cmdX, config, "vdump", dumpkeys, "60", "-", device, NULL); } else #endif /* } */ { #ifndef RESTORE #define RESTORE "restore" #endif #ifdef HAVE_HONOR_NODUMP # define PARAM_HONOR_NODUMP "h" #else # define PARAM_HONOR_NODUMP "" #endif #ifdef __FreeBSD__ # if defined(__FreeBSD_version) && (__FreeBSD_version >= 500043) # define FREEBSD_EXTRA_KEYS "bL" # else # define FREEBSD_EXTRA_KEYS "b" # endif #else # define FREEBSD_EXTRA_KEYS "" #endif dumpkeys = g_strjoin(NULL, level_str, !dle->record ? "" : "u", FREEBSD_EXTRA_KEYS, "s", PARAM_HONOR_NODUMP, "f", NULL); indexcmd = g_strjoin(NULL, RESTORE, " -tvf", " -", " 2>&1", /* not to /dev/null because of DU's dump */ " | ", LEAF_AND_DIRS, NULL); info_tapeheader(dle); start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd); dumppid = pipespawn(cmd, STDIN_PIPE, 0, &dumpin, &dumpout, &mesgf, cmdX, config, "dump", dumpkeys, #ifdef __FreeBSD__ "64", #endif "1048576", #ifdef HAVE_HONOR_NODUMP "0", #endif "-", device, NULL); } #else /* } { */ /* AIX backup program */ dumpkeys = g_strjoin(NULL, "-", level_str, !dle->record ? "" : "u", "f", NULL); indexcmd = g_strjoin(NULL, RESTORE, " -B", " -tvf", " -", " 2>/dev/null", " | ", LEAF_AND_DIRS, NULL); info_tapeheader(dle); start_index(dle->create_index, dumpout, mesgf, indexf, indexcmd); dumppid = pipespawn(cmd, STDIN_PIPE, 0, &dumpin, &dumpout, &mesgf, cmdX, config, "backup", dumpkeys, "-", device, NULL); #endif /* } */ amfree(dumpkeys); amfree(fstype); amfree(device); amfree(cmd); amfree(indexcmd); /* close the write ends of the pipes */ aclose(dumpin); aclose(dumpout); aclose(compout); aclose(dataf); aclose(mesgf); if (dle->create_index) aclose(indexf); }
template<typename PointT, typename NormalT> void pcl::NormalSpaceSampling<PointT, NormalT>::applyFilter (std::vector<int> &indices) { if (!initCompute ()) { indices = *indices_; return; } unsigned int max_values = (std::min) (sample_, static_cast<unsigned int> (input_normals_->size ())); // Resize output indices to sample size indices.resize (max_values); removed_indices_->resize (max_values); // Allocate memory for the histogram of normals. Normals will then be sampled from each bin. unsigned int n_bins = binsx_ * binsy_ * binsz_; // list<int> holds the indices of points in that bin. Using list to avoid repeated resizing of vectors. // Helps when the point cloud is large. std::vector<std::list <int> > normals_hg; normals_hg.reserve (n_bins); for (unsigned int i = 0; i < n_bins; i++) normals_hg.emplace_back(); for (std::vector<int>::const_iterator it = indices_->begin (); it != indices_->end (); ++it) { unsigned int bin_number = findBin (input_normals_->points[*it].normal, n_bins); normals_hg[bin_number].push_back (*it); } // Setting up random access for the list created above. Maintaining the iterators to individual elements of the list // in a vector. Using vector now as the size of the list is known. std::vector<std::vector<std::list<int>::iterator> > random_access (normals_hg.size ()); for (size_t i = 0; i < normals_hg.size (); i++) { random_access.emplace_back(); random_access[i].resize (normals_hg[i].size ()); size_t j = 0; for (std::list<int>::iterator itr = normals_hg[i].begin (); itr != normals_hg[i].end (); itr++, j++) random_access[i][j] = itr; } std::vector<size_t> start_index (normals_hg.size ()); start_index[0] = 0; size_t prev_index = 0; for (size_t i = 1; i < normals_hg.size (); i++) { start_index[i] = prev_index + normals_hg[i-1].size (); prev_index = start_index[i]; } // Maintaining flags to check if a point is sampled boost::dynamic_bitset<> is_sampled_flag (input_normals_->points.size ()); // Maintaining flags to check if all points in the bin are sampled boost::dynamic_bitset<> bin_empty_flag (normals_hg.size ()); unsigned int i = 0; while (i < sample_) { // Iterating through every bin and picking one point at random, until the required number of points are sampled. for (size_t j = 0; j < normals_hg.size (); j++) { unsigned int M = static_cast<unsigned int> (normals_hg[j].size ()); if (M == 0 || bin_empty_flag.test (j)) // bin_empty_flag(i) is set if all points in that bin are sampled.. continue; unsigned int pos = 0; unsigned int random_index = 0; // Picking up a sample at random from jth bin do { random_index = static_cast<unsigned int> ((*rng_uniform_distribution_) () % M); pos = start_index[j] + random_index; } while (is_sampled_flag.test (pos)); is_sampled_flag.flip (start_index[j] + random_index); // Checking if all points in bin j are sampled. if (isEntireBinSampled (is_sampled_flag, start_index[j], static_cast<unsigned int> (normals_hg[j].size ()))) bin_empty_flag.flip (j); unsigned int index = *(random_access[j][random_index]); indices[i] = index; i++; if (i == sample_) break; } } // If we need to return the indices that we haven't sampled if (extract_removed_indices_) { std::vector<int> indices_temp = indices; std::sort (indices_temp.begin (), indices_temp.end ()); std::vector<int> all_indices_temp = *indices_; std::sort (all_indices_temp.begin (), all_indices_temp.end ()); set_difference (all_indices_temp.begin (), all_indices_temp.end (), indices_temp.begin (), indices_temp.end (), inserter (*removed_indices_, removed_indices_->begin ())); } }