Exemple #1
0
/**
 * Converts a path to a simple conjunctive query.
 *
 * @param path The (not necessarily canonical) path to be parsed.
 * @returns A pointer to a tree structure representing the query, or NULL if an
 * error occurred. If an error occurs, \c errno is set appropriately.
 */
qelem *path_to_query(const char *path) {
  if (!path) return NULL;

  char *dup = get_canonical_path(path);
  DEBUG("Canonical path: \"%s\"", path);
  if (!dup || errno) {
    DEBUG("Error in get_canonical_path()");
    if (dup) ifree(dup);
    errno=ENOENT;
    return NULL;
  }
  char *tmp = dup;
  qelem *qroot=NULL;

  /* remove leading slash characters */
  while (*tmp && *tmp=='/')
    tmp++;

  /* If we have a zero-length path, then that matches any tag */
  if (!*tmp) {
    DEBUG("Top-level ISANY");
    qroot = _qtree_make_isany();

  } else {
    int res = strsplitmap(tmp, '/', _path_to_query_proc, (unsigned long)&qroot);

    if (res==0) {
      DEBUG("Success");
    } else if (res==-ENOENT) {
      DEBUG("A component of the path does not exist");
      qtree_free(&qroot, 1);
      ifree(dup);
      errno=ENOENT;
      return NULL;
    } else {
      DEBUG("Problem with strsplitmap");
      qtree_free(&qroot, 1);
      ifree(dup);
      errno=-res;
      return NULL;
    }

    if (_qtree_contains(qroot, QUERY_IS_INODE) && !query_inode_count(qroot)) {
      /* cannot find that inode with the query */
      DEBUG("Could not find the given file");
      qtree_free(&qroot, 1);
      ifree(dup);
      errno=ENOENT;
      return NULL;
    }
  }

  DEBUG("Dumping tree...");
  _qtree_dump(qroot, 0);
  DEBUG("Tree dump done.");

  ifree(dup);
  return qroot;
}
Exemple #2
0
/**
 * Recursively free a query tree.
 *
 * @param root      The address of the root element to be freed.
 * @param free_tags If true, will also free tags (if non-null).
 */
void qtree_free(qelem **root, int free_tags) {
  /* trivial cases */
  if (!root)  return;
  if (!*root) return;

  if (free_tags && (*root)->tag) {
    ifree((*root)->tag);
  }

  qtree_free(&((*root)->next[0]), free_tags);
  qtree_free(&((*root)->next[1]), free_tags);
  ifree(*root);
  *root=NULL;
}
Exemple #3
0
static void generate_grid(DATA *d, double samplespacing, int neighbourhood) {
	DPOINT pt;
	int i, j, n;

	d->n_list = d->n_sel = 0;
	qtree_free(d->qtree_root);
	d->qtree_root = NULL;
	pt.z = 0.0;
	pt.attr = 0.0;
	n = floor(sqrt(neighbourhood)) / 2 + 1;
	d->maxX = d->maxY = n * samplespacing;
	d->minX = d->minY = -n * samplespacing;
	gl_split = 4 * n * n;
	for (i = 0; i < n; i++) {
		for (j = 0; j < n; j++) {
			pt.x = (i + 0.5) * samplespacing;
			pt.y = (j + 0.5) * samplespacing;
			push_point(d, &pt); /* NE */
			pt.y *= -1;
			push_point(d, &pt); /* SE */
			pt.x *= -1;
			push_point(d, &pt); /* SW */
			pt.y *= -1;
			push_point(d, &pt); /* NE */
		}
	}
	d->sel_max = neighbourhood;
	return;
}
Exemple #4
0
/**
 * Small procedure to create a basic conjunctive query tree from a tokenised path.
 *
 * @param str  Incoming path token.
 * @param data A qelem** in disguise that should be updated.
 * @return Always zero.
 */
static int _path_to_query_proc(const char *str, unsigned long data) {
  DEBUG("str: \"%s\"", str);
  qelem *newnode=NULL;
  qelem **qroot=(qelem**)data;
  int is_tag = get_tag(str);
  unsigned long path_hash = hash_path(str);
  int is_file = have_file_by_hash(path_hash);

  if (is_tag) {
    tdata dblock;
    if (tree_read(is_tag, (tblock*)&dblock)) {
      PMSG(LOG_ERR, "I/O error reading block\n");
      qtree_free(qroot, 1);
      return -EIO;
    }
    if (dblock.flags & DATA_FLAGS_NOSUB) {
      newnode=_qtree_make_is_nosub(str);
    } else {
      newnode=_qtree_make_is(str);
    }

  } else if (is_file) {
    newnode=_qtree_make_is_inode(path_hash);

  } else {
    DEBUG("Tag \"%s\" does not exist");
    qtree_free(qroot, 1);
    return -ENOENT;
  }

  if (*qroot) {
    *qroot=_qtree_make_and(newnode, *qroot);
  } else {
    *qroot=newnode;
  }
  return 0;
}
Exemple #5
0
void qtree_free(QTREE_NODE *node) {
/*
 * If a push or search fails, you might want to consider getting rid of 
 * whole tree and default to exhaustive search. (SJ)
 * [If you ever get so far, exhaustive search will take
 * a nearly infinite amount of time. Instead, tweek gl_split. --EJP]
 */
	int i;

	if (node == NULL)
		return;

	if (!is_leaf(node)) {
		for (i = 0; i < N_NODES(node); i++)
			qtree_free(node->u.node[i]);
		efree(node->u.node);
	} else
		efree(node->u.list);
	efree(node);
	return;
}
Exemple #6
0
void free_data(DATA *d) {
	int i;

	assert(d);
	if (DEBUG_FORCE) /* let atexit(qtree_print) do it's job... */
		return;
	if (d->P_base) { /* segmented: */
		efree(d->P_base);
		if (d->n_X && d->X_base)
			efree(d->X_base);
	} else { /* non-segmented */
		if (d->list) /* CW at all MV on output both P_base and d_list are 0 */
			for (i = d->n_list - 1; i >= 0; i--)
				pop_point(d, i);
	}

	if (d->sel != NULL && d->sel != d->list)
		efree(d->sel);
	if (d->list) 
		efree(d->list);
	if (d->colX) 
		efree(d->colX);

	if (d->qtree_root != NULL)
		qtree_free(d->qtree_root);

	if (d->lm) 
		free_lm(d->lm);
	if (d->glm) 
		free_glm(d->glm);

	if (d->grid)
		free_data_gridmap(d->grid);

    if (d->point_ids)
        for (i = d->n_list - 1; i >= 0; i--)
            efree(d->point_ids[i]);
	efree(d);
	return;
}