Esempio n. 1
0
/*
 * pt_set_domain_class() -  set SM_DOMAIN's class field
 *   return:  none
 *   dom(out): an SM_DOMAIN
 *   nam(in): an entity name
 *   virt(in):
 */
static void
pt_set_domain_class (SM_DOMAIN * dom, const PT_NODE * nam, const DB_OBJECT * virt)
{
  if (!dom || !nam || nam->node_type != PT_NAME)
    return;

  dom->type = PR_TYPE_FROM_ID (DB_TYPE_OBJECT);
  if (virt != NULL)
    {
      dom->class_mop = (DB_OBJECT *) virt;
    }
  else
    {
      if (nam->info.name.db_object != NULL)
	{
	  dom->class_mop = nam->info.name.db_object;
	  COPY_OID (&dom->class_oid, &(dom->class_mop->oid_info.oid));
	}
      else
	{
	  dom->class_mop = db_find_class (nam->info.name.original);
	  if (dom->class_mop != NULL)
	    {
	      COPY_OID (&dom->class_oid, &(dom->class_mop->oid_info.oid));
	    }
	}
    }
}
Esempio n. 2
0
/*
 * disk_insert_instance - This inserts a new object in the database given a
 * "descriptor" for the object.
 *    return: NO_ERROR if successful, error code otherwise
 *    classop(in): class object
 *    obj(in): object description
 *    oid(in): oid of the destination
 */
int
disk_insert_instance (MOP classop, DESC_OBJ * obj, OID * oid)
{
  int error = NO_ERROR;
  HFID *hfid;
  int newsize;
  bool has_indexes;

  Diskrec->length = 0;
  if (desc_obj_to_disk (obj, Diskrec, &has_indexes))
    {
      /* make the record larger */
      newsize = -Diskrec->length + DB_PAGESIZE;
      free_recdes (Diskrec);
      Diskrec = alloc_recdes (newsize);
      /* try one more time */
      if (Diskrec == NULL || desc_obj_to_disk (obj, Diskrec, &has_indexes) != 0)
	{
	  error = ER_LDR_CANT_TRANSFORM;
	  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
	}
    }

  if (!error)
    {
      hfid = get_class_heap (classop, obj->class_);
      if (hfid == NULL)
	{
	  assert (er_errid () != NO_ERROR);
	  error = er_errid ();
	}
      else
	{
	  HEAP_OPERATION_CONTEXT context;

	  /* set up context */
	  heap_create_insert_context (&context, hfid, WS_OID (classop), Diskrec, NULL, false);

	  /* oid is set here as a side effect */
	  if (heap_insert_logical (NULL, &context) != NO_ERROR)
	    {
	      assert (er_errid () != NO_ERROR);
	      error = er_errid ();
	    }
	  else if (has_indexes)
	    {
	      COPY_OID (oid, &context.res_oid);
	      error = update_indexes (WS_OID (classop), oid, Diskrec);
	    }
	  else
	    {
	      COPY_OID (oid, &context.res_oid);
	    }
	}
    }
  return (error);
}
Esempio n. 3
0
static int
cursor_prefetch_first_hidden_oid (CURSOR_ID * cursor_id_p)
{
  char *tuple_p;
  OID *current_oid_p;
  QFILE_TUPLE current_tuple;
  int tupel_count, oid_index = 0, current_tuple_length, i;
  DB_TYPE type;

  /* set tuple count and point to the first tuple */
  tupel_count = QFILE_GET_TUPLE_COUNT (cursor_id_p->buffer);
  current_tuple = cursor_id_p->buffer + QFILE_PAGE_HEADER_SIZE;
  oid_index = 0;

  /*
   * search through the current buffer to store interesting OIDs
   * in the oid_set area, eliminating duplicates.
   */
  for (i = 0; i < tupel_count; i++)
    {
      current_tuple_length = QFILE_GET_TUPLE_LENGTH (current_tuple);

      /* fetch first OID */
      type = cursor_id_p->list_id.type_list.domp[0]->type->id;
      tuple_p = (char *) current_tuple + QFILE_TUPLE_LENGTH_SIZE;

      if (QFILE_GET_TUPLE_VALUE_FLAG (tuple_p) != V_BOUND)
	{
	  continue;
	}

      current_oid_p = cursor_get_oid_from_tuple (tuple_p, type);

      if (current_oid_p && oid_index < cursor_id_p->oid_ent_count)
	{
	  COPY_OID (&cursor_id_p->oid_set[oid_index], current_oid_p);
	  oid_index++;
	}

      /* move to next tuple */
      current_tuple = (char *) current_tuple + current_tuple_length;
    }

  return cursor_fetch_oids (cursor_id_p, oid_index,
			    cursor_id_p->prefetch_lock_mode,
			    (cursor_id_p->prefetch_lock_mode ==
			     DB_FETCH_WRITE) ? DB_FETCH_QUERY_WRITE :
			    DB_FETCH_QUERY_READ);
}
Esempio n. 4
0
/*
 * compactdb_start - Compact classes   
 *    return: error code
 *    verbose_flag(in):
 *    delete_old_repr_flag(in): delete old class representations from catalog
 *    input_filename(in): classes file name
 *    input_class_names(in): classes list
 *    input_class_length(in): classes list length
 *    max_processed_space(in): maximum space to process for one iteration
 */
static int
compactdb_start (bool verbose_flag, bool delete_old_repr_flag,
		 char *input_filename,
		 char **input_class_names, int input_class_length,
		 int max_processed_space, int instance_lock_timeout,
		 int class_lock_timeout, DB_TRAN_ISOLATION tran_isolation)
{
  int status = NO_ERROR;
  OID **class_oids = NULL, *next_oid = NULL;
  int i, num_classes = 0;
  LIST_MOPS *class_table = NULL;
  OID last_processed_class_oid, last_processed_oid;
  int *total_objects = NULL, *iteration_total_objects = NULL;
  int *failed_objects = NULL, *iteration_failed_objects = NULL;
  int *modified_objects = NULL, *iteration_modified_objects = NULL;
  char *incomplete_processing = NULL;
  int *big_objects = NULL, *iteration_big_objects = NULL;
  int *initial_last_repr = NULL;
  MOP *class_mops = NULL;
  int last_completed_class_index, temp_index;
  int num_class_mops = 0;
  SM_CLASS *class_ptr = NULL;
  int num_classes_fully_compacted = 0;
  char *class_name = NULL;
  MOP *processed_class_mops = NULL;

  if (input_filename && input_class_names && input_class_length > 0)
    {
      return ER_FAILED;
    }

  status = compact_db_start ();
  if (status != NO_ERROR)
    {
      if (status == ER_COMPACTDB_ALREADY_STARTED)
	{
	  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				  MSGCAT_UTIL_SET_COMPACTDB,
				  COMPACTDB_MSG_ALREADY_STARTED));
	}

      return ER_FAILED;
    }

  tran_reset_wait_times ((float) class_lock_timeout);
  if (input_class_names && input_class_length > 0)
    {
      status = get_class_mops (input_class_names, input_class_length,
			       &class_mops, &num_class_mops);
      if (status != NO_ERROR)
	{
	  goto error;
	}
    }
  else if (input_filename)
    {
      status = get_class_mops_from_file (input_filename, &class_mops,
					 &num_class_mops);
      if (status != NO_ERROR)
	{
	  goto error;
	}
    }
  else
    {
      class_table =
	locator_get_all_mops (sm_Root_class_mop, DB_FETCH_QUERY_READ);
      if (!class_table)
	{
	  status = ER_FAILED;
	  goto error;
	}

      class_mops = class_table->mops;
      num_class_mops = class_table->num;
    }

  class_oids = (OID **) malloc (DB_SIZEOF (OID *) * (num_class_mops));
  if (class_oids == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  for (i = 0; i < num_class_mops; i++)
    {
      class_oids[i] = NULL;
    }

  processed_class_mops = (DB_OBJECT **) malloc (DB_SIZEOF (DB_OBJECT *) *
						(num_class_mops));
  if (processed_class_mops == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  for (i = 0; i < num_class_mops; i++)
    {
      processed_class_mops[i] = NULL;
    }

  num_classes = 0;
  for (i = 0; i < num_class_mops; i++)
    {
      ws_find (class_mops[i], (MOBJ *) & class_ptr);
      if (class_ptr == NULL)
	{
	  continue;
	}

      if (class_ptr->class_type != SM_CLASS_CT)
	{
	  continue;
	}

      class_oids[num_classes] = ws_oid (class_mops[i]);
      if (class_oids[num_classes] != NULL)
	{
	  processed_class_mops[num_classes] = class_mops[i];
	  num_classes++;
	}
    }

  if (num_classes == 0)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_NOTHING_TO_PROCESS));
      goto error;
    }

  total_objects = (int *) malloc (num_classes * sizeof (int));
  if (total_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  iteration_total_objects = (int *) malloc (num_classes * sizeof (int));
  if (iteration_total_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  failed_objects = (int *) malloc (num_classes * sizeof (int));
  if (failed_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  iteration_failed_objects = (int *) malloc (num_classes * sizeof (int));
  if (iteration_failed_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  modified_objects = (int *) malloc (num_classes * sizeof (int));
  if (modified_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  iteration_modified_objects = (int *) malloc (num_classes * sizeof (int));
  if (iteration_modified_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  big_objects = (int *) malloc (num_classes * sizeof (int));
  if (big_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  iteration_big_objects = (int *) malloc (num_classes * sizeof (int));
  if (iteration_big_objects == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  initial_last_repr = (int *) malloc (num_classes * sizeof (int));
  if (initial_last_repr == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  incomplete_processing = (char *) malloc (num_classes * sizeof (char));
  if (incomplete_processing == NULL)
    {
      status = ER_FAILED;
      goto error;
    }

  for (i = 0; i < num_classes; i++)
    {
      total_objects[i] = 0;
      failed_objects[i] = 0;
      modified_objects[i] = 0;
      big_objects[i] = 0;
      incomplete_processing[i] = 0;
      initial_last_repr[i] = NULL_REPRID;
    }

  for (i = 0; i < num_class_mops; i++)
    {
      status = locator_flush_all_instances (class_mops[i], true);
      if (status != NO_ERROR)
	{
	  goto error;
	}
    }

  status = db_commit_transaction ();
  if (status != NO_ERROR)
    {
      goto error;
    }

  COPY_OID (&last_processed_class_oid, class_oids[0]);
  OID_SET_NULL (&last_processed_oid);
  temp_index = -1;
  last_completed_class_index = -1;

  if (verbose_flag)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_PASS1));
    }

  while (true)
    {
      status = db_set_isolation (tran_isolation);
      if (status != NO_ERROR)
	{
	  if (verbose_flag)
	    {
	      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				      MSGCAT_UTIL_SET_COMPACTDB,
				      COMPACTDB_MSG_ISOLATION_LEVEL_FAILURE));
	    }

	  status = ER_FAILED;
	  goto error;
	}

      status = boot_compact_classes (class_oids, num_classes,
				     max_processed_space,
				     instance_lock_timeout * 1000,
				     class_lock_timeout * 1000,
				     delete_old_repr_flag,
				     &last_processed_class_oid,
				     &last_processed_oid,
				     iteration_total_objects,
				     iteration_failed_objects,
				     iteration_modified_objects,
				     iteration_big_objects,
				     initial_last_repr);

      if (OID_ISNULL (&last_processed_class_oid))
	{
	  temp_index = num_classes;
	}
      else
	{
	  temp_index = find_oid (&last_processed_class_oid,
				 class_oids, num_classes);
	}

      switch (status)
	{
	case NO_ERROR:
	  if (delete_old_repr_flag &&
	      temp_index - 1 > last_completed_class_index)
	    {
	      for (i = last_completed_class_index + 1; i < temp_index; i++)
		{
		  if (initial_last_repr[i] == COMPACTDB_REPR_DELETED)
		    {
		      sm_destroy_representations (processed_class_mops[i]);
		    }
		}
	    }

	  status = db_commit_transaction ();
	  if (status != NO_ERROR)
	    {
	      goto error;
	    }
	  break;

	case ER_LK_UNILATERALLY_ABORTED:
	  status = tran_abort_only_client (false);
	  if (status != NO_ERROR)
	    {
	      goto error;
	    }
	  break;

	case ER_FAILED:
	  status = db_abort_transaction ();
	  if (status != NO_ERROR)
	    {
	      goto error;
	    }
	  break;

	default:
	  db_abort_transaction ();
	  status = ER_FAILED;
	  goto error;
	}

      for (i = 0; i < num_classes; i++)
	{
	  if (iteration_total_objects[i] >= 0)
	    {
	      total_objects[i] += iteration_total_objects[i];
	      failed_objects[i] += iteration_failed_objects[i];
	      modified_objects[i] += iteration_modified_objects[i];
	      big_objects[i] += iteration_big_objects[i];
	    }
	  else
	    {
	      incomplete_processing[i] = iteration_total_objects[i];
	    }
	}

      if (temp_index - 1 > last_completed_class_index)
	{
	  for (i = last_completed_class_index + 1; i < temp_index; i++)
	    {
	      status = db_set_isolation (tran_isolation);
	      if (status != NO_ERROR)
		{
		  if (verbose_flag)
		    {
		      printf (msgcat_message
			      (MSGCAT_CATALOG_UTILS,
			       MSGCAT_UTIL_SET_COMPACTDB,
			       COMPACTDB_MSG_ISOLATION_LEVEL_FAILURE));
		    }

		  status = ER_FAILED;
		  goto error;
		}

	      tran_reset_wait_times ((float) class_lock_timeout);
	      show_statistics
		(class_oids[i],
		 incomplete_processing[i] != COMPACTDB_LOCKED_CLASS,
		 incomplete_processing[i] != COMPACTDB_INVALID_CLASS,
		 incomplete_processing[i] != COMPACTDB_UNPROCESSED_CLASS,
		 total_objects[i], failed_objects[i],
		 modified_objects[i], big_objects[i],
		 delete_old_repr_flag,
		 initial_last_repr[i] == COMPACTDB_REPR_DELETED);

	      db_commit_transaction ();
	    }

	  last_completed_class_index = temp_index - 1;
	}

      if (OID_ISNULL (&last_processed_class_oid))
	{
	  break;
	}
    }

  if (verbose_flag)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_PASS2));
    }
  status = do_reclaim_addresses (class_oids, num_classes,
				 &num_classes_fully_compacted, verbose_flag,
				 (float) class_lock_timeout);
  if (status != NO_ERROR)
    {
      goto error;
    }

  if (verbose_flag)
    {
      printf (msgcat_message (MSGCAT_CATALOG_UTILS,
			      MSGCAT_UTIL_SET_COMPACTDB,
			      COMPACTDB_MSG_PASS3));
    }

  for (i = 0; i < num_classes; i++)
    {
      status = db_set_isolation (tran_isolation);
      if (status != NO_ERROR)
	{
	  if (verbose_flag)
	    {
	      printf (msgcat_message
		      (MSGCAT_CATALOG_UTILS,
		       MSGCAT_UTIL_SET_COMPACTDB,
		       COMPACTDB_MSG_ISOLATION_LEVEL_FAILURE));
	    }

	  status = ER_FAILED;
	  goto error;
	}

      tran_reset_wait_times ((float) class_lock_timeout);

      status = boot_heap_compact (class_oids[i]);
      switch (status)
	{
	case NO_ERROR:
	  status = db_commit_transaction ();
	  if (status != NO_ERROR)
	    {
	      goto error;
	    }
	  break;

	case ER_LK_UNILATERALLY_ABORTED:
	  status = tran_abort_only_client (false);
	  if (status != NO_ERROR)
	    {
	      goto error;
	    }
	  break;

	default:
	  status = db_abort_transaction ();
	  if (status != NO_ERROR)
	    {
	      goto error;
	    }
	  break;
	}

      class_name = get_name_from_class_oid (class_oids[i]);
      if (class_name == NULL)
	{
	  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				  MSGCAT_UTIL_SET_COMPACTDB,
				  COMPACTDB_MSG_UNKNOWN_CLASS_NAME));
	}
      else
	{
	  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				  MSGCAT_UTIL_SET_COMPACTDB,
				  COMPACTDB_MSG_CLASS), class_name);
	}

      if (status != NO_ERROR)
	{
	  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				  MSGCAT_UTIL_SET_COMPACTDB,
				  COMPACTDB_MSG_HEAP_COMPACT_FAILED));
	}
      else
	{
	  printf (msgcat_message (MSGCAT_CATALOG_UTILS,
				  MSGCAT_UTIL_SET_COMPACTDB,
				  COMPACTDB_MSG_HEAP_COMPACT_SUCCEEDED));
	}

      if (class_name)
	{
	  free (class_name);
	  class_name = NULL;
	}

      db_commit_transaction ();
    }

error:
  if (class_oids)
    {
      free_and_init (class_oids);
    }

  if (processed_class_mops)
    {
      free_and_init (processed_class_mops);
    }

  if (total_objects)
    {
      free_and_init (total_objects);
    }

  if (iteration_total_objects)
    {
      free_and_init (iteration_total_objects);
    }

  if (failed_objects)
    {
      free_and_init (failed_objects);
    }

  if (iteration_failed_objects)
    {
      free_and_init (iteration_failed_objects);
    }

  if (modified_objects)
    {
      free_and_init (modified_objects);
    }

  if (iteration_modified_objects)
    {
      free_and_init (iteration_modified_objects);
    }

  if (big_objects)
    {
      free_and_init (big_objects);
    }

  if (iteration_big_objects)
    {
      free_and_init (iteration_big_objects);
    }

  if (initial_last_repr)
    {
      free_and_init (initial_last_repr);
    }

  if (incomplete_processing)
    {
      free_and_init (incomplete_processing);
    }

  if (class_table)
    {
      locator_free_list_mops (class_table);
    }
  else
    {
      if (class_mops)
	{
	  for (i = 0; i < num_class_mops; i++)
	    {
	      class_mops[i] = NULL;
	    }

	  free_and_init (class_mops);
	}
    }

  compact_db_stop ();

  return status;
}
Esempio n. 5
0
static int
cursor_prefetch_column_oids (CURSOR_ID * cursor_id_p)
{
  char *tuple_p;
  OID *current_oid_p;
  QFILE_TUPLE current_tuple;
  int tuple_count, oid_index = 0, current_tuple_length;
  int j, tuple_index, col_index, col_num;
  DB_TYPE type;

  /* set tuple count and point to the first tuple */
  tuple_count = QFILE_GET_TUPLE_COUNT (cursor_id_p->buffer);
  current_tuple = cursor_id_p->buffer + QFILE_PAGE_HEADER_SIZE;
  oid_index = 0;

  for (tuple_index = 0; tuple_index < tuple_count; tuple_index++)
    {
      current_tuple_length = QFILE_GET_TUPLE_LENGTH (current_tuple);

      for (col_index = 0; col_index < cursor_id_p->oid_col_no_cnt;
	   col_index++)
	{
	  col_num = cursor_id_p->oid_col_no[col_index];
	  type = cursor_id_p->list_id.type_list.domp[col_num]->type->id;

	  tuple_p = (char *) current_tuple + QFILE_TUPLE_LENGTH_SIZE;
	  for (j = col_num - 1; j >= 0; --j)
	    {
	      tuple_p +=
		QFILE_TUPLE_VALUE_HEADER_SIZE +
		QFILE_GET_TUPLE_VALUE_LENGTH (tuple_p);
	    }

	  if (QFILE_GET_TUPLE_VALUE_FLAG (tuple_p) != V_BOUND)
	    {
	      continue;
	    }

	  if (type != DB_TYPE_OBJECT && type != DB_TYPE_VOBJ)
	    {
	      continue;
	    }

	  current_oid_p = cursor_get_oid_from_tuple (tuple_p, type);

	  if (current_oid_p && oid_index < cursor_id_p->oid_ent_count)
	    {
	      /* for little endian */
	      if (type == DB_TYPE_VOBJ)
		{
		  OR_PUT_OID (&cursor_id_p->oid_set[oid_index],
			      current_oid_p);
		}
	      else
		{
		  COPY_OID (&cursor_id_p->oid_set[oid_index], current_oid_p);
		}

	      oid_index++;
	    }
	}

      current_tuple = (char *) current_tuple + current_tuple_length;
    }

  return cursor_fetch_oids (cursor_id_p, oid_index, DB_FETCH_READ,
			    DB_FETCH_QUERY_READ);
}
Esempio n. 6
0
 /*
  * boot_compact_db - compact specified classes
  * HEAP_CACHE_ATTRINFO structure
  *    return: error status
  *    class_oids(in): the classes list
  *    n_classes(in): the class_oids length
  * hfids(in):  the hfid list
  *    space_to_process(in): the space to process
  *    instance_lock_timeout(in): the lock timeout for instances
  *    class_lock_timeout(in): the lock timeout for instances
  *    delete_old_repr(in):  whether to delete the old class representation
  *    last_processed_class_oid(in,out): last processed class oid
  *    last_processed_oid(in,out): last processed oid
  *    total_objects(out): count processed objects for each class
  *    failed_objects(out): count failed objects for each class
  *    modified_objects(out): count modified objects for each class
  *    big_objects(out): count big objects for each class
  *    initial_last_repr_id(in, out): the list of initial last class 
  * representation
  */
int
boot_compact_db (THREAD_ENTRY * thread_p, OID * class_oids, int n_classes,
		 int space_to_process,
		 int instance_lock_timeout,
		 int class_lock_timeout,
		 bool delete_old_repr,
		 OID * last_processed_class_oid,
		 OID * last_processed_oid,
		 int *total_objects, int *failed_objects,
		 int *modified_objects, int *big_objects,
		 int *initial_last_repr_id)
{
  int result = NO_ERROR;
  int i, j, start_index = -1;
  int max_space_to_process, current_tran_index = -1;
  int lock_ret;
  HFID hfid;

  if (boot_can_compact (thread_p) == false)
    {
      return ER_COMPACTDB_ALREADY_STARTED;
    }

  if (class_oids == NULL || n_classes <= 0 ||
      space_to_process <= 0 || last_processed_class_oid == NULL ||
      last_processed_oid == NULL || total_objects == NULL ||
      failed_objects == NULL || modified_objects == NULL ||
      big_objects == NULL || initial_last_repr_id == NULL)
    {
      return ER_QPROC_INVALID_PARAMETER;
    }

  for (start_index = 0; start_index < n_classes; start_index++)
    {
      if (OID_EQ (class_oids + start_index, last_processed_class_oid))
	{
	  break;
	}
    }

  if (start_index == n_classes)
    {
      return ER_QPROC_INVALID_PARAMETER;
    }

  for (i = 0; i < n_classes; i++)
    {
      total_objects[i] = 0;
      failed_objects[i] = 0;
      modified_objects[i] = 0;
      big_objects[i] = 0;
    }

  max_space_to_process = space_to_process;
  for (i = start_index; i < n_classes; i++)
    {
      lock_ret = lock_object_waitsecs (thread_p, class_oids + i,
				       oid_Root_class_oid, IX_LOCK,
				       LK_UNCOND_LOCK, class_lock_timeout);

      if (lock_ret != LK_GRANTED)
	{
	  total_objects[i] = COMPACTDB_LOCKED_CLASS;
	  OID_SET_NULL (last_processed_oid);
	  continue;
	}

      if (heap_get_hfid_from_class_oid (thread_p, class_oids + i, &hfid) !=
	  NO_ERROR)
	{
	  lock_unlock_object (thread_p, class_oids + i, oid_Root_class_oid,
			      IX_LOCK, true);
	  OID_SET_NULL (last_processed_oid);
	  total_objects[i] = COMPACTDB_INVALID_CLASS;
	  continue;
	}

      if (HFID_IS_NULL (&hfid))
	{
	  lock_unlock_object (thread_p, class_oids + i, oid_Root_class_oid,
			      IX_LOCK, true);
	  OID_SET_NULL (last_processed_oid);
	  total_objects[i] = COMPACTDB_INVALID_CLASS;
	  continue;
	}

      if (OID_ISNULL (last_processed_oid))
	{
	  initial_last_repr_id[i] =
	    heap_get_class_repr_id (thread_p, class_oids + i);
	  if (initial_last_repr_id[i] <= 0)
	    {
	      lock_unlock_object (thread_p, class_oids + i,
				  oid_Root_class_oid, IX_LOCK, true);
	      total_objects[i] = COMPACTDB_INVALID_CLASS;
	      continue;
	    }
	}

      if (process_class
	  (thread_p, class_oids + i, &hfid, max_space_to_process,
	   &instance_lock_timeout, &space_to_process,
	   last_processed_oid, total_objects + i,
	   failed_objects + i, modified_objects + i, big_objects + i) !=
	  NO_ERROR)
	{
	  OID_SET_NULL (last_processed_oid);
	  for (j = start_index; j <= i; j++)
	    {
	      total_objects[j] = COMPACTDB_UNPROCESSED_CLASS;
	      failed_objects[j] = 0;
	      modified_objects[j] = 0;
	      big_objects[j] = 0;
	    }

	  result = ER_FAILED;
	  break;
	}

      if (delete_old_repr &&
	  OID_ISNULL (last_processed_oid) && failed_objects[i] == 0 &&
	  heap_get_class_repr_id (thread_p, class_oids + i) ==
	  initial_last_repr_id[i])
	{
	  lock_ret = lock_object_waitsecs (thread_p, class_oids + i,
					   oid_Root_class_oid, X_LOCK,
					   LK_UNCOND_LOCK,
					   class_lock_timeout);
	  if (lock_ret == LK_GRANTED)
	    {
	      if (catalog_drop_old_representations (thread_p, class_oids + i)
		  != NO_ERROR)
		{
		  for (j = start_index; j <= i; j++)
		    {
		      total_objects[j] = COMPACTDB_UNPROCESSED_CLASS;
		      failed_objects[j] = 0;
		      modified_objects[j] = 0;
		      big_objects[j] = 0;
		    }

		  result = ER_FAILED;
		}
	      else
		{
		  initial_last_repr_id[i] = COMPACTDB_REPR_DELETED;
		}

	      break;
	    }
	}

      if (space_to_process == 0)
	{
	  break;
	}
    }

  if (OID_ISNULL (last_processed_oid))
    {
      if (i < n_classes - 1)
	{
	  COPY_OID (last_processed_class_oid, class_oids + i + 1);
	}
      else
	{
	  OID_SET_NULL (last_processed_class_oid);
	}
    }
  else
    {
      COPY_OID (last_processed_class_oid, class_oids + i);
    }

  return result;
}
Esempio n. 7
0
/*
 * process_class - process a class
 * HEAP_CACHE_ATTRINFO structure
 *    return: error status
 *    class_oid(in): the class OID
 *    hfid(in): the class HFID 
 *    max_space_to_process(in): maximum space to process
 *    instance_lock_timeout(in): the lock timeout for instances
 *    space_to_process(in, out): space to process
 *    last_processed_oid(in, out): last processed oid
 *    total_objects(in, out): count the processed class objects
 *    failed_objects(in, out): count the failed class objects
 *    modified_objects(in, out): count the modified class objects
 *    big_objects(in, out): count the big class objects
 */
static int
process_class (THREAD_ENTRY * thread_p, OID * class_oid, HFID * hfid,
	       int max_space_to_process, int *instance_lock_timeout,
	       int *space_to_process, OID * last_processed_oid,
	       int *total_objects, int *failed_objects,
	       int *modified_objects, int *big_objects)
{
  int nobjects, nfetched, i, j;
  OID last_oid, prev_oid;
  LOCK null_lock = NULL_LOCK;
  LOCK oid_lock = X_LOCK;
  LC_COPYAREA *fetch_area = NULL;	/* Area where objects are received */
  struct lc_copyarea_manyobjs *mobjs;	/* Describe multiple objects in area */
  struct lc_copyarea_oneobj *obj;	/* Describe on object in area        */
  RECDES recdes;
  HEAP_CACHE_ATTRINFO attr_info;
  HEAP_SCANCACHE upd_scancache;
  int ret = NO_ERROR, object_processed;

  int nfailed_instances = 0;

  if (class_oid == NULL || hfid == NULL || space_to_process == NULL ||
      *space_to_process <= 0 || *space_to_process > max_space_to_process ||
      last_processed_oid == NULL || total_objects == NULL ||
      failed_objects == NULL || modified_objects == NULL ||
      big_objects == NULL || *total_objects < 0 || *failed_objects < 0)
    {
      return ER_FAILED;
    }

  nobjects = 0;
  nfetched = -1;

  ret =
    heap_scancache_start_modify (thread_p, &upd_scancache, hfid, class_oid,
				 SINGLE_ROW_UPDATE);
  if (ret != NO_ERROR)
    {
      return ER_FAILED;
    }

  ret = heap_attrinfo_start (thread_p, class_oid, -1, NULL, &attr_info);
  if (ret != NO_ERROR)
    {
      heap_scancache_end_modify (thread_p, &upd_scancache);
      return ER_FAILED;
    }

  COPY_OID (&last_oid, last_processed_oid);
  COPY_OID (&prev_oid, last_processed_oid);

  while (nobjects != nfetched)
    {
      ret = xlocator_lock_and_fetch_all (thread_p, hfid, &oid_lock,
					 instance_lock_timeout, class_oid,
					 &null_lock, &nobjects, &nfetched,
					 &nfailed_instances, &last_oid,
					 &fetch_area);

      if (ret == NO_ERROR)
	{
	  (*total_objects) += nfailed_instances;
	  (*failed_objects) += nfailed_instances;

	  if (fetch_area != NULL)
	    {
	      mobjs = LC_MANYOBJS_PTR_IN_COPYAREA (fetch_area);
	      obj = LC_START_ONEOBJ_PTR_IN_COPYAREA (mobjs);

	      for (i = 0; i < mobjs->num_objs; i++)
		{
		  if (obj->length > *space_to_process)
		    {
		      if (*space_to_process == max_space_to_process)
			{
			  (*total_objects)++;
			  (*big_objects)++;
			  lock_unlock_object (thread_p, &obj->oid, class_oid,
					      oid_lock, true);
			}
		      else
			{
			  *space_to_process = 0;
			  COPY_OID (last_processed_oid, &prev_oid);

			  for (j = i; j < mobjs->num_objs; j++)
			    {
			      lock_unlock_object (thread_p, &obj->oid,
						  class_oid, oid_lock, true);
			      obj = LC_NEXT_ONEOBJ_PTR_IN_COPYAREA (obj);
			    }

			  if (fetch_area)
			    {
			      locator_free_copy_area (fetch_area);
			    }
			  goto end;
			}
		    }
		  else
		    {
		      *space_to_process -= obj->length;

		      (*total_objects)++;
		      LC_RECDES_TO_GET_ONEOBJ (fetch_area, obj, &recdes);

		      if (desc_disk_to_attr_info
			  (thread_p, &obj->oid, &recdes,
			   &attr_info) == NO_ERROR)
			{
			  object_processed = process_object
			    (thread_p, &upd_scancache, &attr_info, &obj->oid);

			  if (object_processed != 1)
			    {
			      lock_unlock_object (thread_p, &obj->oid,
						  class_oid, oid_lock, true);

			      if (object_processed == -1)
				{
				  (*failed_objects)++;
				}
			    }
			  else
			    {
			      (*modified_objects)++;
			    }
			}
		      else
			{
			  (*failed_objects)++;
			}
		    }

		  COPY_OID (&prev_oid, &obj->oid);
		  obj = LC_NEXT_ONEOBJ_PTR_IN_COPYAREA (obj);
		}

	      if (fetch_area)
		{
		  locator_free_copy_area (fetch_area);
		}
	    }
	  else
	    {
	      /* No more objects */
	      break;
	    }
	}
      else
	{
	  ret = ER_FAILED;
	  break;
	}
    }

  COPY_OID (last_processed_oid, &last_oid);

end:

  heap_attrinfo_end (thread_p, &attr_info);
  heap_scancache_end_modify (thread_p, &upd_scancache);

  return ret;
}
Esempio n. 8
0
/*
 * disk_insert_instance_using_mobj - inserts a new object in the database
 * given a memory object and class object
 *    return: NO_ERROR if successful, error code otherwise
 *    classop(in): class object
 *    classobj(in): class memory object
 *    obj(in): object memory.
 *    oid(out): oid of the destination
 */
int
disk_insert_instance_using_mobj (MOP classop, MOBJ classobj, MOBJ obj, OID * oid)
{
  int error = NO_ERROR;
  HFID *hfid;
  volatile int newsize = 0;
  bool has_indexes;
  TF_STATUS tf_status = TF_SUCCESS;

  Diskrec->length = 0;

  /* 
   * tf_mem_to_disk() is used to get an estimate of the disk space requirements
   * for the object. When dealing with collections the estimate returned is
   * not always a good one, hence we need to enclose this block in a loop
   * increasing the space by increments of DB_PAGESIZE until we hit the correct
   * space requirement.
   */
  while ((tf_status = tf_mem_to_disk (classop, classobj, obj, Diskrec, &has_indexes)) == TF_OUT_OF_SPACE)
    {
      /* make the record larger */
      if (newsize)
	{
	  newsize += DB_PAGESIZE;
	}
      else
	{
	  newsize = -Diskrec->length + DB_PAGESIZE;
	}
      free_recdes (Diskrec);
      Diskrec = alloc_recdes (newsize);
      if (Diskrec == NULL)
	{
	  assert (er_errid () != NO_ERROR);
	  error = er_errid ();
	  break;
	}
    }
  if (tf_status != TF_SUCCESS)
    {
      error = ER_LDR_CANT_TRANSFORM;
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0);
    }

  if (error == NO_ERROR && Diskrec != NULL)
    {
      hfid = get_class_heap (classop, (SM_CLASS *) classop->object);
      if (hfid == NULL)
	{
	  assert (er_errid () != NO_ERROR);
	  error = er_errid ();
	}
      else
	{
	  HEAP_OPERATION_CONTEXT context;

	  /* set up context */
	  heap_create_insert_context (&context, hfid, WS_OID (classop), Diskrec, NULL);

	  /* oid is set here as a side effect */
	  if (heap_insert_logical (NULL, &context) != NO_ERROR)
	    {
	      assert (er_errid () != NO_ERROR);
	      error = er_errid ();
	    }
	  else if (has_indexes)
	    {
	      COPY_OID (oid, &context.res_oid);
	      error = update_indexes (WS_OID (classop), oid, Diskrec);
	    }
	  else
	    {
	      COPY_OID (oid, &context.res_oid);
	    }
	}
    }
  return (error);
}