Exemplo n.º 1
0
static void remove_output_from_cache(t_session *session, char *request_uri, t_cot_type cot_type) {
	t_cached_object *object;
	char *url;
	int index;

	if ((url = make_url(session, request_uri)) == NULL) {
		return;
	} else if ((index = cache_index(url)) == -1) {
		free(url);
		return;
	}

	pthread_mutex_lock(&cache_mutex[index]);

	object = cache[index];
	while (object != NULL) {
		if (object->type == cot_type) {
			if (strcmp(object->file, url) == 0) {
				if (object->in_use <= 0) {
					remove_from_cache(object, index);
				} else {
					object->deadline = 0;
				}
				break;
			}
		}
		object = object->next;
	}

	pthread_mutex_unlock(&cache_mutex[index]);

	free(url);
}
Exemplo n.º 2
0
/***********************************************************************//**
 * @brief Return instrument response to diffuse source
 *
 * @param[in] event Observed event.
 * @param[in] source Source.
 * @param[in] obs Observation.
 * @return Instrument response to diffuse source.
 *
 * Returns the instrument response to a specified diffuse source.
 *
 * The method uses a pre-computation cache to store the instrument response
 * for the spatial model component. The pre-computation cache is initialised
 * if no cache has yet been allocated, or if at the beginning of a scan over
 * the events, the model parameters have changed. The beginning of a scan is
 * defined by an event bin index of 0.
 ***************************************************************************/
double GCTAResponseCube::irf_diffuse(const GEvent&       event,
                                     const GSource&      source,
                                     const GObservation& obs) const
{
    // Initialise IRF
    double irf = 0.0;

    // Get pointer to CTA event bin
    if (!event.is_bin()) {
        std::string msg = "The current event is not a CTA event bin. "
                          "This method only works on binned CTA data. Please "
                          "make sure that a CTA observation containing binned "
                          "CTA data is provided.";
        throw GException::invalid_value(G_IRF_DIFFUSE, msg);
    }
    const GCTAEventBin* bin = static_cast<const GCTAEventBin*>(&event);

    // Get pointer to source cache. We first search the cache for a model
    // with the source name. If no model was found we initialise a new
    // cache entry for that model. Otherwise, we simply return the actual
    // cache entry.
    GCTACubeSourceDiffuse* cache(NULL);
    int index = cache_index(source.name());
    if (index == -1) {
    
        // No cache entry was found, thus allocate and initialise a new one
        cache = new GCTACubeSourceDiffuse;
        cache->set(source.name(), *source.model(), obs);
        m_cache.push_back(cache);

    } // endif: no cache entry was found
    else {
    
        // Check that the cache entry is of the expected type
        if (m_cache[index]->code() != GCTA_CUBE_SOURCE_DIFFUSE) {
            std::string msg = "Cached model \""+source.name()+"\" is not "
                              "an extended source model. This method only "
                              "applies to extended source models.";
            throw GException::invalid_value(G_IRF_DIFFUSE, msg);
        }
        cache = static_cast<GCTACubeSourceDiffuse*>(m_cache[index]);

    } // endelse: there was a cache entry for this model

    // Determine IRF value
    irf = cache->irf(bin->ipix(), bin->ieng());

    // Compile option: Check for NaN/Inf
    #if defined(G_NAN_CHECK)
    if (gammalib::is_notanumber(irf) || gammalib::is_infinite(irf)) {
        std::cout << "*** ERROR: GCTAResponseCube::irf_diffuse:";
        std::cout << " NaN/Inf encountered";
        std::cout << " irf=" << irf;
        std::cout << std::endl;
    }
    #endif

    // Return IRF value
    return irf;
}
Exemplo n.º 3
0
gboolean
c2_db_cronosII_message_add (C2Mailbox *mailbox, C2Db *db)
{
	gint mid = 0;
	FILE *fd;
	gchar *buf;
	C2MessageState state;

	/* Initialization */
	if (!cache_index (mailbox))
		return FALSE;

	_lock (mailbox);
	fd = mailbox->protocol.cronosII.fd;

	/* Get the MID */
	if (mailbox->db)
		mid = mailbox->db->prev->prev->mid+1;

	if (!mid)
		mid = 1;

	db->mid = mid;
	
	fseek (fd, 0, SEEK_END);

	switch (db->state)
	{
		case C2_MESSAGE_READED: state = ' '; break;
		default:
		case C2_MESSAGE_UNREADED: state = 'N'; break;
		case C2_MESSAGE_REPLIED: state = 'R'; break;
		case C2_MESSAGE_FORWARDED: state = 'F'; break;
	}

	fprintf (fd, "%c\r\r%d\r%s\r%s\r%d\r%s\r%d\n",
					state, db->mark, db->subject, db->from,
					db->date, db->account, db->mid);

	/* Now write to its own file */
	buf = g_strdup_printf ("%s" C2_HOME "%s.mbx/%d", g_get_home_dir (), mailbox->name, db->mid);
	if (!(fd = fopen (buf, "w")))
	{
		g_free (buf);
		c2_error_object_set (GTK_OBJECT (mailbox), -errno);
		return FALSE;
	}
	g_free (buf);

	fprintf (fd, "%s\n\n%s", db->message->header, db->message->body);
	fclose (fd);

	_rewind (mailbox);
	_unlock (mailbox);

	return TRUE;
}
Exemplo n.º 4
0
t_cached_object *search_cache(t_session *session, char *file) {
    off_t size;

    if(file == NULL) {
        return NULL;
    } else if((size = filesize(file)) == -1) {
        return NULL;
    }

    int i;

    if((i = cache_index(file)) == -1) {
        return NULL;
    }

    pthread_mutex_lock(&cache_mutex[i]);

    t_cached_object *object = cache[i], *result = NULL;
    struct stat status;
    /*object = cache[i];*/

    while(object != NULL) {
        if(object->size == size) {
            if (strcmp(object->file, file) == 0) {
                if(stat(file, &status) == 0) {
                    if((object->deadline > session->time) && (status.st_mtime == object->last_changed)) {
                        if(same_ip(&(object->last_ip), &(session->ip_address)) == false) {
                            if((object->deadline += TIME_IN_CACHE) > (session->time + MAX_CACHE_TIMER)) {
                                object->deadline = session->time + MAX_CACHE_TIMER;
                            }
                            copy_ip(&(object->last_ip), &(session->ip_address));
                        }
                        object->in_use++;
                        result = object;
                    } else if(object->in_use <= 0) {
                        remove_from_cache(object, i);
                    }
                } else if(object->in_use <= 0) {
                    remove_from_cache(object, i);
                }
                break;
            }
        }
        object = object->next;
    }

    pthread_mutex_unlock(&cache_mutex[i]);

    return result;
}
Exemplo n.º 5
0
        /// Optimization for when the cache index has already been computed
        inline stored_type* get(const intptr_t (&vtbl)[N], size_t j) noexcept
        {
            XTL_ASSERT(vtbl[0]); // Must be a valid vtbl pointer
            XTL_ASSERT(vtbl[1]); // Must be a valid vtbl pointer
            XTL_ASSERT(j == cache_index(vtbl)); // j must be index of location where vtbl should be
            stored_type*& ce = cache[j]; // Location where it should be

            XTL_ASSERT(ce);   // Since we pre-allocate all entries

            if (XTL_UNLIKELY(ce->vtbl[0] != vtbl[0] || 
                             ce->vtbl[1] != vtbl[1]))
            {
                // NOTE: We don't check if the entry is occupied as even when 
                //       it is not, the vtbl may be elsewhere in the cache due 
                //       to changes to k and l after update.
                stored_type** cv;

                // See if (vtbl0,vtbl1) is elsewhere in the cache
                for (size_t i = 0; i <= cache_mask; ++i)
                    if (cache[i]->vtbl[0] == vtbl[0] && 
                        cache[i]->vtbl[1] == vtbl[1]) // if so ...
                    {
                        cv = &cache[i]; // swap it with the right position
                        goto Swap;
                    }

                // (vtbl0,vtbl1) is not in the cache
                if (used <= cache_mask) // there are empty slots in cache
                    for (size_t i = 0; i <= cache_mask; ++i)
                        if (cache[i]->vtbl[0] == 0) // find the first empty slot
                        {
                            XTL_ASSERT(cache[i]->vtbl[1] == 0);
                            cache[i]->vtbl[0] = vtbl[0]; // assign vtbl to it
                            cache[i]->vtbl[1] = vtbl[1]; // assign vtbl to it
                            ++used;
                            cv = &cache[i]; // swap it with the right position
                            goto Swap;
                        }

                // There are no empty slots, we return nullptr to indicate this.
                return 0;
Swap:
                std::swap(ce,*cv);
            }

            return ce;
        }
Exemplo n.º 6
0
        /// Re-establishes invariant that vtbls can only be in the cache 
        /// entry that correspond to their cache index, unless that entry
        /// is already taken.
        void put_entries_in_right_place()
        {
            for (size_t i = 0; i <= cache_mask; ++i)
            {
                size_t k = ~0; // Keeps cache index of the previous swap.

                while (cache[i]->vtbl[0]) // There is a valid tuple of vtbl pointers in the entry
                {
                    XTL_ASSERT(cache[i]->vtbl[N-1]);        // Either all 0 or all non 0
                    size_t j = cache_index(cache[i]->vtbl); // Index of location where it should be

                    if (j != k && j != i) // where it should be is not where previous one was swapped to and not here
                    {
                        std::swap(cache[i],cache[j]); // swap current to where it should be
                        k = j;                        // remember where we swapped it to
                    }
                    else
                        break;
                }
            }
        }
Exemplo n.º 7
0
static bool add_object_to_cache(t_cached_object *object) {
	int index;
	t_cached_object *search;

	if (object == NULL) {
		return false;
	} else if ((index = cache_index(object->file)) == -1) {
		return false;
	}

	pthread_mutex_lock(&cache_mutex[index]);

	object->prev = NULL;
	object->next = cache[index];
	if (cache[index] != NULL) {
		cache[index]->prev = object;

		search = cache[index];
		while (search != NULL) {
			if (strcmp(search->file, object->file) == 0) {
				search->deadline = 0;
				break;
			}
			search = search->next;
		}
	}
	cache[index] = object;

	pthread_mutex_lock(&cache_size_mutex);
	cache_size += object->size;
	pthread_mutex_unlock(&cache_size_mutex);

	pthread_mutex_unlock(&cache_mutex[index]);

	return true;
}
Exemplo n.º 8
0
static t_cached_object *search_cache_for_output(t_session *session, t_cot_type cot_type) {
	t_cached_object *object, *result = NULL;
	char *url;
	int index;

	if ((url = make_url(session, NULL)) == NULL) {
		return NULL;
	} else if ((index = cache_index(url)) == -1) {
		free(url);
		return NULL;
	}

	pthread_mutex_lock(&cache_mutex[index]);

	object = cache[index];
	while (object != NULL) {
		if (object->type == cot_type) {
			if (strcmp(object->file, url) == 0) {
				if (object->deadline > session->time) {
					object->in_use++;
					result = object;
				} else if (object->in_use <= 0) {
					remove_from_cache(object, index);
				}
				break;
			}
		}
		object = object->next;
	}

	pthread_mutex_unlock(&cache_mutex[index]);

	free(url);

	return result;
}
Exemplo n.º 9
0
 /// Main function that will be used to get a reference to the stored element. 
 inline stored_type* get(const intptr_t (&vtbl)[N]) noexcept
 {
     size_t j = cache_index(vtbl);
     return get(vtbl,j);
 }
Exemplo n.º 10
0
 /// Computes cache index for current optimal offsets and cache mask.
 size_t cache_index(const intptr_t vtbl[N]) const { return cache_index(vtbl,optimal_shift,cache_mask); }
Exemplo n.º 11
0
t_cached_object *add_to_cache(t_session *session, char *file) {
    t_cached_object *object;
    struct stat status;
    off_t size;
    int fd, i;
    size_t bytes_read, bytes_total = 0;

    if(file == NULL) {
        return NULL;
    } else if (stat(file, &status) == -1) {
        return NULL;
    } else if((size = status.st_size) == -1) {
        return NULL;
    } else if((size < session->config->cache_min_filesize) || (size > session->config->cache_max_filesize)) {
        return NULL;
    } else if(cachesize + size > session->config->cache_size) {
        return NULL;
    } else if((object = (t_cached_object*)malloc(sizeof(t_cached_object))) == NULL) {
        return NULL;
    } else if((object->file = strdup(file)) == NULL) {
        free(object);
        return NULL;
    } else if((object->data = (char*)malloc(size)) == NULL) {
        free(object->file);
        free(object);
        return NULL;
    }

    if((fd = open(file, O_RDONLY)) != -1) {
        while(bytes_total < size) {
            if((bytes_read = read(fd, object->data + bytes_total, size - bytes_total)) == -1) {
                if(errno != EINTR) {
                    free(object->data);
                    free(object->file);
                    free(object);
                    close(fd);
                    return NULL;
                }
            } else {
                bytes_total += bytes_read;
            }
        }
        close(fd);
    } else {
        free(object->data);
        free(object->file);
        free(object);
        return NULL;
    }

    object->last_changed = status.st_mtime;
    object->deadline = session->time + TIME_IN_CACHE;
    object->size = size;
    object->in_use = 1;
    copy_ip(&(object->last_ip), &(session->ip_address));

    if((i = cache_index(file)) == -1) {
        free(object->data);
        free(object->file);
        free(object);
        return NULL;
    }

    pthread_mutex_lock(&cache_mutex[i]);

    object->prev = NULL;
    object->next = cache[i];

    if(cache[i] != NULL) {
        cache[i]->prev = object;
    }

    cache[i] = object;
    pthread_mutex_lock(&cachesize_mutex);
    cachesize += object->size;
    pthread_mutex_unlock(&cachesize_mutex);
    pthread_mutex_unlock(&cache_mutex[i]);

    return object;
}
Exemplo n.º 12
0
/**
 * c2_db_cronosII_load
 * @mailbox: Mailbox to load.
 *
 * Will load the Cronos II Mailbox.
 *
 * Return Value:
 * Number of loaded messages or -1 in case of error.
 **/
gint
c2_db_cronosII_load (C2Mailbox *mailbox)
{
	C2Db *current = NULL, *next;
	FILE *fd;
	gint position, mid;
	gchar c, *line, *buf;
	gboolean mark;
	time_t date;

	c2_return_val_if_fail_obj (mailbox, -1, C2EDATA, GTK_OBJECT (mailbox));	

	/* Initialization */
	if (!cache_index (mailbox))
		return -1;
	
	_lock (mailbox);
	fd = mailbox->protocol.cronosII.fd;
	_rewind (mailbox);
	
	/* Go through the lines */
	for (position = 0;;)
	{
		if (fread (&c, 1, sizeof (gchar), fd) < 1)
			break;

		/* A D has been reached */
		if (c == 'D')
		{
			/* Lets go to the next line.. */
			if (!c2_fd_move_to (fd, '\n', 1, TRUE, TRUE))
				break;

			/* .. and start again */
			continue;
		}

		/* Now that we know this is an interesting line,
		 * lets grab it.
		 */
		if (!(line = c2_fd_get_line (fd)))
		{
			c2_error_object_set (GTK_OBJECT (mailbox), c2_errno);
			break;
		}

		/* Create the new C2Db */
		buf = c2_str_get_word (5, line, '\r');
		date = atoi (buf);
		g_free (buf);

		buf = c2_str_get_word (7, line, '\r');
		mid = atoi (buf);
		g_free (buf);
		mailbox->protocol.cronosII.mid = mid;

		buf = c2_str_get_word (2, line, '\r');
		mark = atoi (buf);
		g_free (buf);

		next = c2_db_new (mailbox, mark, c2_str_get_word (3, line, '\r'),
							c2_str_get_word (4, line, '\r'),
							c2_str_get_word (6, line, '\r'),
							date, mid, ++position);

		switch (c)
		{
			default:
			case ' ': next->state = C2_MESSAGE_READED; break;
			case 'N': next->state = C2_MESSAGE_UNREADED; break;
			case 'R': next->state = C2_MESSAGE_REPLIED; break;
			case 'F': next->state = C2_MESSAGE_FORWARDED; break;
		}

		/* Append it to the list */
		if (current)
			current->next = next;

		if (!mailbox->db)
			mailbox->db = next;

		current = next;
	}
	
	_unlock (mailbox);
	_rewind (mailbox);

	return position;
}
Exemplo n.º 13
0
/**
 * This function will go to an specific MID
 * in an index file.
 **/
static gboolean
goto_mid (C2Mailbox *mailbox, gint req_mid)
{
	gboolean found = FALSE;
	gint line_length;
	
	if (!cache_index (mailbox))
		return FALSE;

	if (mailbox->protocol.cronosII.mid < req_mid)
	{
current_mid_less_than_req_mid:

		/* Go through the lines */
		for (;;)
		{
			gint fmid;

			if ((fmid = mid_in_line (mailbox, &line_length)) < 0)
			{
				found = FALSE;
				_rewind (mailbox);
				break;
			}
			
			if (fmid == req_mid)
			{
				found = TRUE;
				break;
			} else
				fseek (mailbox->protocol.cronosII.fd, line_length, SEEK_CUR);
		}
	} else if (mailbox->protocol.cronosII.mid > req_mid)
	{
		/* FIXME This is an ugly thing to do, lets change it */
		_rewind (mailbox);
		goto current_mid_less_than_req_mid;

		/* Go through the lines backwards */
		for (;;)
		{
			if (!c2_fd_move_to (mailbox->protocol.cronosII.fd, '\n', 1, FALSE, TRUE))
			{
move_error:
				c2_error_object_set (GTK_OBJECT (mailbox), c2_errno);
				found = FALSE;
				_rewind (mailbox);
				break;
			} else
			{
				if (!c2_fd_move_to (mailbox->protocol.cronosII.fd, '\r', 7, FALSE, FALSE))
					goto move_error;
				if (fseek (mailbox->protocol.cronosII.fd, -1, SEEK_CUR) < 0)
				{
					c2_error_set (-errno);
					goto move_error;
				}

				if (mid_in_line_reverse (mailbox, &line_length) == req_mid)
				{
					found = TRUE;
					break;
				} else
					fseek (mailbox->protocol.cronosII.fd, -(line_length+1), SEEK_CUR);
			}
		}
	} else
		found = TRUE;

	return found;
}