コード例 #1
0
ファイル: tags_cache.c プロジェクト: nihlaeth/read-the-room
static void *locked_read_add (struct tags_cache *c, const char *file,
                              const int tags_sel, const int client_id,
                              DBT *key, DBT *serialized_cache_rec)
{
	int ret;
	struct file_tags *tags = NULL;

	assert (c->db != NULL);

	ret = c->db->get (c->db, NULL, key, serialized_cache_rec, 0);
	if (ret && ret != DB_NOTFOUND)
		logit ("Cache DB get error: %s", db_strerror (ret));

	/* If this entry is already present in the cache, we have 3 options:
	 * we must read different tags (TAGS_*) or the tags are outdated
	 * or this is an immediate tags read (client_id == -1) */
	if (ret == 0) {
		struct cache_record rec;

		if (cache_record_deserialize (&rec, serialized_cache_rec->data,
		                              serialized_cache_rec->size, 0)) {
			time_t curr_mtime = get_mtime (file);

			if (rec.mod_time != curr_mtime) {
				debug ("Tags in the cache are outdated");
				tags_free (rec.tags);  /* remove them and reread tags */
			}
			else if ((rec.tags->filled & tags_sel) == tags_sel
					&& client_id == -1) {
				debug ("Tags are in the cache.");
				return rec.tags;
			}
			else {
				debug ("Tags in the cache are not what we want");
				tags = rec.tags;  /* read additional tags */
			}
		}
	}

	tags = read_missing_tags (file, tags, tags_sel);
	tags_cache_add (c, file, key, tags);

	return tags;
}
コード例 #2
0
ファイル: tags_cache.c プロジェクト: Manishearth/moc
/* Read the selected tags for this file and add it to the cache.
 * If client_id != -1, the server is notified using tags_response().
 * If client_id == -1, copy of file_tags is returned. */
static struct file_tags *tags_cache_read_add (struct tags_cache *c,
		const int client_id, const char *file, int tags_sel)
{
	struct file_tags *tags = NULL;
	DBT key;
	DBT serialized_cache_rec;
	DB_LOCK lock;
	int got_lock = 0;
	int ret;

	assert (c != NULL);
	assert (c->db != NULL);
	assert (file != NULL);

	debug ("Getting tags for %s", file);

	memset (&key, 0, sizeof(key));
	memset (&serialized_cache_rec, 0, sizeof(serialized_cache_rec));

	key.data = (void *)file;
	key.size = strlen(file);
	serialized_cache_rec.flags = DB_DBT_MALLOC;

	ret = c->db_env->lock_get (c->db_env, c->locker, 0,
			&key, DB_LOCK_WRITE, &lock);
	if (ret) {
		logit ("Can't get DB lock: %s", db_strerror(ret));
	}
	else {
		got_lock = 1;
		ret = c->db->get (c->db, NULL, &key, &serialized_cache_rec, 0);
		if (ret && ret != DB_NOTFOUND)
			logit ("Cache DB get error: %s", db_strerror(ret));
	}

	/* If this entry is already present in the cache, we have 3 options:
	 * we must read different tags (TAGS_*) or the tags are outdated
	 * or this is an immediate tags read (client_id == -1) */
	if (ret == 0) {
		struct cache_record rec;

		if (cache_record_deserialize (&rec, serialized_cache_rec.data,
		                              serialized_cache_rec.size, 0)) {
			time_t curr_mtime = get_mtime (file);

			if (rec.mod_time != curr_mtime) {

				/* outdated tags - remove them and reread */
				tags_free (rec.tags);

				debug ("Tags in the cache are outdated");
			}
			else if ((rec.tags->filled & tags_sel) == tags_sel
					&& client_id == -1) {
				debug ("Tags are in the cache.");
				tags = rec.tags;

				goto end;
			}
			else {
				tags = rec.tags; /* read tags in addition to already
						      present tags */
				debug ("Tags in the cache are not what we want.");
			}
		}
	}

	if (tags == NULL)
		tags = tags_new ();

	if (tags_sel & TAGS_TIME) {
		int time;

		/* Try to get it from the server's playlist first. */
		time = audio_get_ftime (file);

		if (time != -1) {
			tags->time = time;
			tags->filled |= TAGS_TIME;
			tags_sel &= ~TAGS_TIME;
		}
	}

	tags = read_file_tags (file, tags, tags_sel);

	debug ("Adding/updating cache object");
	tags_cache_add (c, file, tags);

	if (client_id != -1) {
		tags_response (client_id, file, tags);
		tags_free (tags);
		tags = NULL;
	}

	/* TODO: Remove the oldest items from the cache if we exceeded the maximum
	 * cache size */

end:
	if (got_lock) {
		ret = c->db_env->lock_put (c->db_env, &lock);
		if (ret)
			logit ("Can't release DB lock: %s", db_strerror(ret));
	}

	if (serialized_cache_rec.data)
		free (serialized_cache_rec.data);

	return tags;
}