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