Ejemplo n.º 1
0
int si_nodeseal(sinode *n, sr *r, siconf *conf)
{
	srpath path;
	sr_pathAB(&path, conf->path, n->self.id.parent,
	          n->self.id.id, ".db.seal");
	int rc = sr_filerename(&n->file, path.path);
	if (srunlikely(rc == -1)) {
		sr_malfunction(r->e, "db file '%s' rename error: %s",
		               n->file.file, strerror(errno));
	}
	return rc;
}
Ejemplo n.º 2
0
int si_nodecreate(sinode *n, sr *r, siconf *conf, sdid *id,
                  sdindex *i,
                  sdbuild *build)
{
	si_branchset(&n->self, i);
	srpath path;
	sr_pathAB(&path, conf->path, id->parent, id->id, ".db.incomplete");
	int rc = sr_filenew(&n->file, path.path);
	if (srunlikely(rc == -1)) {
		sr_malfunction(r->e, "db file '%s' create error: %s",
		               path.path, strerror(errno));
		return -1;
	}
	rc = sd_buildwrite(build, r, &n->self.index, &n->file);
	if (srunlikely(rc == -1))
		return -1;
	n->branch = &n->self;
	n->branch_count++;
	return 0;
}
Ejemplo n.º 3
0
static inline int
si_trackdir(sitrack *track, sr *r, si *i)
{
	DIR *dir = opendir(i->conf->path);
	if (srunlikely(dir == NULL)) {
		sr_malfunction(r->e, "directory '%s' open error: %s",
		               i->conf->path, strerror(errno));
		return -1;
	}
	struct dirent *de;
	while ((de = readdir(dir))) {
		if (srunlikely(de->d_name[0] == '.'))
			continue;
		uint32_t id_parent = 0;
		uint32_t id = 0;
		int rc = si_process(de->d_name, &id, &id_parent);
		if (srunlikely(rc == -1))
			continue; /* skip unknown file */
		si_tracknsn(track, id_parent);
		si_tracknsn(track, id);

		sinode *head, *node;
		srpath path;
		switch (rc) {
		case SI_RDB_DBI:
		case SI_RDB_DBSEAL: {
			/* find parent node and mark it as having
			 * incomplete compaction process */
			head = si_trackget(track, id_parent);
			if (srlikely(head == NULL)) {
				head = si_nodenew(r);
				if (srunlikely(head == NULL))
					goto error;
				head->self.id.id = id_parent;
				head->recover = SI_RDB_UNDEF;
				si_trackset(track, head);
			}
			head->recover |= rc;
			/* remove any incomplete file made during compaction */
			if (rc == SI_RDB_DBI) {
				sr_pathAB(&path, i->conf->path, id_parent, id, ".db.incomplete");
				rc = sr_fileunlink(path.path);
				if (srunlikely(rc == -1)) {
					sr_malfunction(r->e, "db file '%s' unlink error: %s",
					               path.path, strerror(errno));
					goto error;
				}
				continue;
			}
			assert(rc == SI_RDB_DBSEAL);
			/* recover 'sealed' node */
			node = si_nodenew(r);
			if (srunlikely(node == NULL))
				goto error;
			node->recover = SI_RDB_DBSEAL;
			sr_pathAB(&path, i->conf->path, id_parent, id, ".db.seal");
			rc = si_nodeopen(node, r, &path);
			if (srunlikely(rc == -1)) {
				si_nodefree(node, r, 0);
				goto error;
			}
			si_trackset(track, node);
			si_trackmetrics(track, node);
			continue;
		}
		}
		assert(rc == SI_RDB);

		/* recover node */
		node = si_nodenew(r);
		if (srunlikely(node == NULL))
			goto error;
		node->recover = SI_RDB;
		sr_pathA(&path, i->conf->path, id, ".db");
		rc = si_nodeopen(node, r, &path);
		if (srunlikely(rc == -1)) {
			si_nodefree(node, r, 0);
			goto error;
		}
		si_trackmetrics(track, node);

		/* track node */
		head = si_trackget(track, id);
		if (srlikely(head == NULL)) {
			si_trackset(track, node);
		} else {
			/* replace a node previously created by a
			 * incomplete compaction. */
			if (! (head->recover & SI_RDB_UNDEF)) {
				sr_malfunction(r->e, "corrupted database repository: %s",
				               i->conf->path);
				goto error;
			}
			si_trackreplace(track, head, node);
			head->recover &= ~SI_RDB_UNDEF;
			node->recover |= head->recover;
			si_nodefree(head, r, 0);
		}
	}
	closedir(dir);
	return 0;
error:
	closedir(dir);
	return -1;
}