Actual source code: petscctable.h
petsc-3.14.6 2021-03-30
1: #ifndef PETSCCTABLE_H
2: #define 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: {
19: return(x%(unsigned long)ta->tablesize);
20: }
22: PETSC_STATIC_INLINE unsigned long PetscHashStep(PetscTable ta,unsigned long x)
23: {
24: return(1+(x%(unsigned long)(ta->tablesize-1)));
25: }
27: PETSC_EXTERN PetscErrorCode PetscTableCreate(const PetscInt,PetscInt,PetscTable*);
28: PETSC_EXTERN PetscErrorCode PetscTableCreateCopy(const PetscTable,PetscTable*);
29: PETSC_EXTERN PetscErrorCode PetscTableDestroy(PetscTable*);
30: PETSC_EXTERN PetscErrorCode PetscTableGetCount(const PetscTable,PetscInt*);
31: PETSC_EXTERN PetscErrorCode PetscTableIsEmpty(const PetscTable,PetscInt*);
32: PETSC_EXTERN PetscErrorCode PetscTableAddExpand(PetscTable,PetscInt,PetscInt,InsertMode);
33: PETSC_EXTERN PetscErrorCode PetscTableAddCountExpand(PetscTable,PetscInt);
34: PETSC_EXTERN PetscErrorCode PetscTableGetHeadPosition(PetscTable,PetscTablePosition*);
35: PETSC_EXTERN PetscErrorCode PetscTableGetNext(PetscTable,PetscTablePosition*,PetscInt*,PetscInt*);
36: PETSC_EXTERN PetscErrorCode PetscTableRemoveAll(PetscTable);
38: PETSC_STATIC_INLINE PetscErrorCode PetscTableAdd(PetscTable ta,PetscInt key,PetscInt data,InsertMode imode)
39: {
41: PetscInt i,hash = (PetscInt)PetscHash(ta,(unsigned long)key);
42: PetscInt hashstep = (PetscInt)PetscHashStep(ta,(unsigned long)key);
45: if (key <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"key <= 0");
46: if (key > ta->maxkey) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"key %D is greater than largest key allowed %D",key,ta->maxkey);
47: if (!data) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Null data");
49: for (i=0; i<ta->tablesize; i++) {
50: if (ta->keytable[hash] == key) {
51: switch (imode) {
52: case INSERT_VALUES:
53: ta->table[hash] = data; /* over write */
54: break;
55: case ADD_VALUES:
56: ta->table[hash] += data;
57: break;
58: case MAX_VALUES:
59: ta->table[hash] = PetscMax(ta->table[hash],data);
60: break;
61: case MIN_VALUES:
62: ta->table[hash] = PetscMin(ta->table[hash],data);
63: break;
64: case NOT_SET_VALUES:
65: case INSERT_ALL_VALUES:
66: case ADD_ALL_VALUES:
67: case INSERT_BC_VALUES:
68: case ADD_BC_VALUES:
69: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported InsertMode");
70: }
71: return(0);
72: } else if (!ta->keytable[hash]) {
73: if (ta->count < 5*(ta->tablesize/6) - 1) {
74: ta->count++; /* add */
75: ta->keytable[hash] = key;
76: ta->table[hash] = data;
77: } else {
78: PetscTableAddExpand(ta,key,data,imode);
79: }
80: return(0);
81: }
82: hash = (hash + hashstep)%ta->tablesize;
83: }
84: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_COR,"Full table");
85: /* return(0); */
86: }
88: PETSC_STATIC_INLINE PetscErrorCode PetscTableAddCount(PetscTable ta,PetscInt key)
89: {
91: PetscInt i,hash = (PetscInt)PetscHash(ta,(unsigned long)key);
92: PetscInt hashstep = (PetscInt)PetscHashStep(ta,(unsigned long)key);
95: if (key <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"key <= 0");
96: if (key > ta->maxkey) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"key %D is greater than largest key allowed %D",key,ta->maxkey);
98: for (i=0; i<ta->tablesize; i++) {
99: if (ta->keytable[hash] == key) {
100: return(0);
101: } else if (!ta->keytable[hash]) {
102: if (ta->count < 5*(ta->tablesize/6) - 1) {
103: ta->count++; /* add */
104: ta->keytable[hash] = key;
105: ta->table[hash] = ta->count;
106: } else {
107: PetscTableAddCountExpand(ta,key);
108: }
109: return(0);
110: }
111: hash = (hash + hashstep)%ta->tablesize;
112: }
113: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_COR,"Full table");
114: /* return(0); */
115: }
117: /*
118: PetscTableFind - checks if a key is in the table
120: If data==0, then no table entry exists.
122: */
123: PETSC_STATIC_INLINE PetscErrorCode PetscTableFind(PetscTable ta,PetscInt key,PetscInt *data)
124: {
125: PetscInt ii = 0;
126: PetscInt hash = (PetscInt)PetscHash(ta,(unsigned long)key);
127: PetscInt hashstep = (PetscInt)PetscHashStep(ta,(unsigned long)key);
130: *data = 0;
131: if (key <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Key <= 0");
132: if (key > ta->maxkey) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"key %D is greater than largest key allowed %D",key,ta->maxkey);
134: while (ii++ < ta->tablesize) {
135: if (!ta->keytable[hash]) break;
136: else if (ta->keytable[hash] == key) {
137: *data = ta->table[hash];
138: break;
139: }
140: hash = (hash + hashstep)%ta->tablesize;
141: }
142: return(0);
143: }
145: #endif