static guint64
arv_gc_register_node_get_length (ArvGcRegister *gc_register, GError **error)
{
	ArvGcRegisterNode *gc_register_node = ARV_GC_REGISTER_NODE (gc_register);

	return _get_length (gc_register_node, error);
}
static guint64
_get_address (ArvGcRegisterNode *gc_register_node, GError **error)
{
	ArvGc *genicam;
	GError *local_error = NULL;
	GSList *iter;
	guint64 value = 0;

	genicam = arv_gc_node_get_genicam (ARV_GC_NODE (gc_register_node));
	g_return_val_if_fail (ARV_IS_GC (genicam), 0);

	for (iter = gc_register_node->addresses; iter != NULL; iter = iter->next) {
		value += arv_gc_property_node_get_int64 (iter->data, &local_error);

		if (local_error != NULL) {
			g_propagate_error (error, local_error);
			return 0;
		}
	}

	for (iter = gc_register_node->swiss_knives; iter != NULL; iter = iter->next) {
		value += arv_gc_integer_get_value (iter->data, &local_error);

		if (local_error != NULL) {
			g_propagate_error (error, local_error);
			return 0;
		}
	}

	if (gc_register_node->index != NULL) {
		gint64 length;

		length = _get_length (gc_register_node, &local_error);

		if (local_error != NULL) {
			g_propagate_error (error, local_error);
			return 0;
		}

		value += arv_gc_index_node_get_index (ARV_GC_INDEX_NODE (gc_register_node->index), length, &local_error);

		if (local_error != NULL) {
			g_propagate_error (error, local_error);
			return 0;
		}
	}

	return value;
}
static void
_update_cache_size (ArvGcRegisterNode *gc_register_node, GError **error)
{
	GError *local_error = NULL;
	gint64 length;

	length = _get_length (gc_register_node, &local_error);

	if (local_error != NULL) {
		g_propagate_error (error, local_error);
		return;
	}

	if (length != gc_register_node->cache_size) {
		g_free (gc_register_node->cache);
		gc_register_node->cache = g_malloc (length);
		gc_register_node->cache_size = length;
	}

}
static gboolean
_push_tail (LogQueueDisk *s, LogMessage *msg, LogPathOptions *local_options, const LogPathOptions *path_options)
{
  LogQueueDiskNonReliable *self = (LogQueueDiskNonReliable *) s;

  if (HAS_SPACE_IN_QUEUE(self->qout) && qdisk_get_length (self->super.qdisk) == 0)
    {
      /* simple push never generates flow-control enabled entries to qout, they only get there
       * when rewinding the backlog */

      g_queue_push_tail (self->qout, msg);
      g_queue_push_tail (self->qout, LOG_PATH_OPTIONS_FOR_BACKLOG);
      log_msg_ref (msg);
    }
  else
    {
      if (self->qoverflow->length != 0 || !s->write_message(s, msg))
        {
          if (HAS_SPACE_IN_QUEUE(self->qoverflow))
            {
              g_queue_push_tail (self->qoverflow, msg);
              g_queue_push_tail (self->qoverflow, LOG_PATH_OPTIONS_TO_POINTER (path_options));
              log_msg_ref (msg);
              local_options->ack_needed = FALSE;
            }
          else
            {
              msg_debug ("Destination queue full, dropping message",
                         evt_tag_str ("filename", qdisk_get_filename (self->super.qdisk)),
                         evt_tag_int ("queue_len", _get_length(s)),
                         evt_tag_int ("mem_buf_length", self->qoverflow_size),
                         evt_tag_int ("size", qdisk_get_size (self->super.qdisk)),
                         evt_tag_str ("persist_name", self->super.super.persist_name));
              return FALSE;
            }
        }
    }
  return TRUE;
}
void test__get_length() {
    assert(2 == _get_length(4, 2));   // above diagonal
    assert(4 == _get_length(4, 0));   // on diagonal
    assert(3 == _get_length(4, -1));  // below diagonal
}