Actual source code: petscctable.h
petsc-3.8.4 2018-03-24
1: #ifndef __PETSCCTABLE_H
3: #include <petscsys.h>
5: struct _n_PetscTable {
6: PetscInt *keytable;
7: PetscInt *table;
8: PetscInt count;
9: PetscInt tablesize;
10: PetscInt head;
11: PetscInt maxkey; /* largest key allowed */
12: };
14: typedef struct _n_PetscTable* PetscTable;
15: typedef PetscInt* PetscTablePosition;
17: PETSC_STATIC_INLINE unsigned long PetscHash(PetscTable ta,unsigned long x)
18: {
20: PetscFunctionReturn(x%(unsigned long)ta->tablesize);
21: }
23: PETSC_STATIC_INLINE unsigned long PetscHashStep(PetscTable ta,unsigned long x)
24: {
26: PetscFunctionReturn(1+(x%(unsigned long)(ta->tablesize-1)));
27: }
29: PETSC_EXTERN PetscErrorCode PetscTableCreate(const PetscInt,PetscInt,PetscTable*);
30: PETSC_EXTERN PetscErrorCode PetscTableCreateCopy(const PetscTable,PetscTable*);
31: PETSC_EXTERN PetscErrorCode PetscTableDestroy(PetscTable*);
32: PETSC_EXTERN PetscErrorCode PetscTableGetCount(const PetscTable,PetscInt*);
33: PETSC_EXTERN PetscErrorCode PetscTableIsEmpty(const PetscTable,PetscInt*);
34: PETSC_EXTERN PetscErrorCode PetscTableAddExpand(PetscTable,PetscInt,PetscInt,InsertMode);
35: PETSC_EXTERN PetscErrorCode PetscTableAddCountExpand(PetscTable,PetscInt);
36: PETSC_EXTERN PetscErrorCode PetscTableGetHeadPosition(PetscTable,PetscTablePosition*);
37: PETSC_EXTERN PetscErrorCode PetscTableGetNext(PetscTable,PetscTablePosition*,PetscInt*,PetscInt*);
38: PETSC_EXTERN PetscErrorCode PetscTableRemoveAll(PetscTable);
40: PETSC_STATIC_INLINE PetscErrorCode PetscTableAdd(PetscTable ta,PetscInt key,PetscInt data,InsertMode imode)
41: {
43: PetscInt i,hash = (PetscInt)PetscHash(ta,(unsigned long)key);
44: PetscInt hashstep = (PetscInt)PetscHashStep(ta,(unsigned long)key);
47: if (key <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"key <= 0");
48: if (key > ta->maxkey) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"key %D is greater than largest key allowed %D",key,ta->maxkey);
49: if (!data) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Null data");
51: for (i=0; i<ta->tablesize; i++) {
52: if (ta->keytable[hash] == key) {
53: switch (imode) {
54: case INSERT_VALUES:
55: ta->table[hash] = data; /* over write */
56: break;
57: case ADD_VALUES:
58: ta->table[hash] += data;
59: break;
60: case MAX_VALUES:
61: ta->table[hash] = PetscMax(ta->table[hash],data);
62: break;
63: case NOT_SET_VALUES:
64: case INSERT_ALL_VALUES:
65: case ADD_ALL_VALUES:
66: case INSERT_BC_VALUES:
67: case ADD_BC_VALUES:
68: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported InsertMode");
69: }
70: return(0);
71: } else if (!ta->keytable[hash]) {
72: if (ta->count < 5*(ta->tablesize/6) - 1) {
73: ta->count++; /* add */
74: ta->keytable[hash] = key;
75: ta->table[hash] = data;
76: } else {
77: PetscTableAddExpand(ta,key,data,imode);
78: }
79: return(0);
80: }
81: hash = (hash + hashstep)%ta->tablesize;
82: }
83: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_COR,"Full table");
84: /* return(0); */
85: }
87: PETSC_STATIC_INLINE PetscErrorCode PetscTableAddCount(PetscTable ta,PetscInt key)
88: {
90: PetscInt i,hash = (PetscInt)PetscHash(ta,(unsigned long)key);
91: PetscInt hashstep = (PetscInt)PetscHashStep(ta,(unsigned long)key);
94: if (key <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"key <= 0");
95: if (key > ta->maxkey) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"key %D is greater than largest key allowed %D",key,ta->maxkey);
97: for (i=0; i<ta->tablesize; i++) {
98: if (ta->keytable[hash] == key) {
99: return(0);
100: } else if (!ta->keytable[hash]) {
101: if (ta->count < 5*(ta->tablesize/6) - 1) {
102: ta->count++; /* add */
103: ta->keytable[hash] = key;
104: ta->table[hash] = ta->count;
105: } else {
106: PetscTableAddCountExpand(ta,key);
107: }
108: return(0);
109: }
110: hash = (hash + hashstep)%ta->tablesize;
111: }
112: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_COR,"Full table");
113: /* return(0); */
114: }
116: /*
117: PetscTableFind - checks if a key is in the table
119: If data==0, then no table entry exists.
121: */
122: PETSC_STATIC_INLINE PetscErrorCode PetscTableFind(PetscTable ta,PetscInt key,PetscInt *data)
123: {
124: PetscInt ii = 0;
125: PetscInt hash = (PetscInt)PetscHash(ta,(unsigned long)key);
126: PetscInt hashstep = (PetscInt)PetscHashStep(ta,(unsigned long)key);
129: *data = 0;
130: if (key <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Key <= 0");
131: if (key > ta->maxkey) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"key %D is greater than largest key allowed %D",key,ta->maxkey);
133: while (ii++ < ta->tablesize) {
134: if (!ta->keytable[hash]) break;
135: else if (ta->keytable[hash] == key) {
136: *data = ta->table[hash];
137: break;
138: }
139: hash = (hash + hashstep)%ta->tablesize;
140: }
141: return(0);
142: }
144: #endif