1 /* ========================================================================== */
2 /* === UMF_mem_alloc_element ================================================ */
3 /* ========================================================================== */
4 
5 /* -------------------------------------------------------------------------- */
6 /* Copyright (c) 2005-2012 by Timothy A. Davis, http://www.suitesparse.com.   */
7 /* All Rights Reserved.  See ../Doc/License.txt for License.                  */
8 /* -------------------------------------------------------------------------- */
9 
10 /* The UMF_mem_* routines manage the Numeric->Memory memory space. */
11 
12 /* Allocate a nrows-by-ncols element, and initialize it. */
13 /* Returns the index into Numeric->Memory if successful, or 0 on failure. */
14 
15 #include "umf_internal.h"
16 #include "umf_mem_alloc_element.h"
17 #include "umf_mem_alloc_tail_block.h"
18 
UMF_mem_alloc_element(NumericType * Numeric,Int nrows,Int ncols,Int ** Rows,Int ** Cols,Entry ** C,Int * size,Element ** epout)19 GLOBAL Int UMF_mem_alloc_element
20 (
21     NumericType *Numeric,
22     Int nrows,
23     Int ncols,
24     Int **Rows,
25     Int **Cols,
26     Entry **C,
27     Int *size,
28     Element **epout
29 )
30 {
31 
32     Element *ep ;
33     Unit *p ;
34     Int i ;
35 
36     ASSERT (Numeric != (NumericType *) NULL) ;
37     ASSERT (Numeric->Memory != (Unit *) NULL) ;
38 
39     *size = GET_ELEMENT_SIZE (nrows, ncols) ;
40     if (INT_OVERFLOW (DGET_ELEMENT_SIZE (nrows, ncols) + 1))
41     {
42 	/* :: allocate element, int overflow :: */
43 	return (0) ;	/* problem is too large */
44     }
45 
46     i = UMF_mem_alloc_tail_block (Numeric, *size) ;
47     (*size)++ ;
48     if (!i)
49     {
50 	DEBUG0 (("alloc element failed - out of memory\n")) ;
51 	return (0) ;	/* out of memory */
52     }
53     p = Numeric->Memory + i ;
54 
55     ep = (Element *) p ;
56 
57     DEBUG2 (("alloc_element done ("ID" x "ID"): p: "ID" i "ID"\n",
58 	nrows, ncols, (Int) (p-Numeric->Memory), i)) ;
59 
60     /* Element data structure, in order: */
61     p += UNITS (Element, 1) ;		/* (1) Element header */
62     *Cols = (Int *) p ;			/* (2) col [0..ncols-1] indices */
63     *Rows = *Cols + ncols ;		/* (3) row [0..nrows-1] indices */
64     p += UNITS (Int, ncols + nrows) ;
65     *C = (Entry *) p ;			/* (4) C [0..nrows-1, 0..ncols-1] */
66 
67     ep->nrows = nrows ;		/* initialize the header information */
68     ep->ncols = ncols ;
69     ep->nrowsleft = nrows ;
70     ep->ncolsleft = ncols ;
71     ep->cdeg = 0 ;
72     ep->rdeg = 0 ;
73     ep->next = EMPTY ;
74 
75     DEBUG2 (("new block size: "ID" ", GET_BLOCK_SIZE (Numeric->Memory + i))) ;
76     DEBUG2 (("Element size needed "ID"\n", GET_ELEMENT_SIZE (nrows, ncols))) ;
77 
78     *epout = ep ;
79 
80     /* return the offset into Numeric->Memory */
81     return (i) ;
82 }
83