]> git.donarmstrong.com Git - mothur.git/blob - path.cpp
555830a9397eefa47fc52a9b1c590d7d50676ab4
[mothur.git] / path.cpp
1 //uchime by Robert C. Edgar http://drive5.com/uchime This code is donated to the public domain.\r
2 \r
3 #include "myutils.h"\r
4 #include "path.h"\r
5 #include "timing.h"\r
6 \r
7 #define TRACE   0\r
8 \r
9 const unsigned PathMagic = 0x9A783A16;\r
10 \r
11 struct PathBuffer\r
12         {\r
13         unsigned Magic;\r
14         char *Buffer;\r
15         unsigned Size;\r
16         bool InUse;\r
17         };\r
18 \r
19 static PathBuffer **g_PathBuffers;\r
20 static unsigned g_PathBufferSize;\r
21 \r
22 static char *AllocBuffer(unsigned Size)\r
23         {\r
24         if (Size == 0)\r
25                 return 0;\r
26 \r
27 // Is a free buffer that is big enough?\r
28         for (unsigned i = 0; i < g_PathBufferSize; ++i)\r
29                 {\r
30                 PathBuffer *PB = g_PathBuffers[i];\r
31                 asserta(PB->Magic == PathMagic);\r
32                 if (!PB->InUse)\r
33                         {\r
34                         if (PB->Size >= Size)\r
35                                 {\r
36                                 PB->InUse = true;\r
37                                 return PB->Buffer;\r
38                                 }\r
39                         if (PB->Buffer == 0)\r
40                                 {\r
41                                 unsigned Size2 = Size + 1024;\r
42                                 PB->Buffer = MYALLOC(char, Size2, Path);\r
43                                 PB->Size = Size2;\r
44                                 PB->InUse = true;\r
45                                 return PB->Buffer;\r
46                                 }\r
47                         }\r
48                 }\r
49 \r
50 // No available buffer, must expand g_PathBuffers[]\r
51         unsigned NewPathBufferSize = g_PathBufferSize + 1024;\r
52         PathBuffer **NewPathBuffers = MYALLOC(PathBuffer *, NewPathBufferSize, Path);\r
53         \r
54         for (unsigned i = 0; i < g_PathBufferSize; ++i)\r
55                 NewPathBuffers[i] = g_PathBuffers[i];\r
56 \r
57         for (unsigned i = g_PathBufferSize; i < NewPathBufferSize; ++i)\r
58                 {\r
59                 PathBuffer *PB = MYALLOC(PathBuffer, 1, Path);\r
60                 PB->Magic = PathMagic;\r
61                 PB->Buffer = 0;\r
62                 PB->Size = 0;\r
63                 PB->InUse = false;\r
64                 NewPathBuffers[i] = PB;\r
65                 }\r
66 \r
67         PathBuffer *PB = NewPathBuffers[g_PathBufferSize];\r
68 \r
69         MYFREE(g_PathBuffers, g_PathBufferSize, Path);\r
70         g_PathBuffers = NewPathBuffers;\r
71         g_PathBufferSize = NewPathBufferSize;\r
72 \r
73         asserta(!PB->InUse && PB->Buffer == 0);\r
74 \r
75         unsigned Size2 = Size + 1024;\r
76         PB->Buffer = MYALLOC(char, Size2, Path);\r
77         PB->Size = Size2;\r
78         PB->InUse = true;\r
79         return PB->Buffer;\r
80         }\r
81 \r
82 static void FreeBuffer(char *Buffer)\r
83         {\r
84         if (Buffer == 0)\r
85                 return;\r
86 \r
87         for (unsigned i = 0; i < g_PathBufferSize; ++i)\r
88                 {\r
89                 PathBuffer *PB = g_PathBuffers[i];\r
90                 if (PB->Buffer == Buffer)\r
91                         {\r
92                         asserta(PB->InUse);\r
93                         PB->InUse = false;\r
94                         return;\r
95                         }\r
96                 }\r
97 \r
98         Die("FreeBuffer, not found");\r
99         }\r
100 \r
101 void PathData::Alloc(unsigned MaxLen)\r
102         {\r
103         if (MaxLen < Bytes)\r
104                 return;\r
105 \r
106         StartTimer(PathAlloc);\r
107         if (Bytes > 0)\r
108                 {\r
109                 FreeBuffer(Front);\r
110                 }\r
111 \r
112         Bytes = MaxLen + 1;\r
113         Front = AllocBuffer(Bytes);\r
114         Back = Front + Bytes - 1;\r
115         Start = 0;\r
116         EndTimer(PathAlloc);\r
117         }\r
118 \r
119 void PathData::Free()\r
120         {\r
121         FreeBuffer(Front);\r
122         Front = 0;\r
123         Start = 0;\r
124         Back = 0;\r
125         }\r
126 \r
127 void PathData::Copy(const PathData &rhs)\r
128         {\r
129         Alloc(rhs.Bytes);\r
130         strcpy(Front, rhs.Front);\r
131         Start = Front + (rhs.Start - rhs.Front);\r
132         }\r
133 \r
134 void PathData::FromStr(const char *PathStr)\r
135         {\r
136         asserta(PathStr != 0);\r
137         unsigned NeededBytes = (unsigned) strlen(PathStr) + 1;\r
138         Alloc(NeededBytes);\r
139         strcpy(Front, PathStr);\r
140         Start = Front;\r
141         }\r
142 \r
143 void LogPathStats()\r
144         {\r
145         Log("\n");\r
146         unsigned Bytes = 0;\r
147         for (unsigned i = 0; i < g_PathBufferSize; ++i)\r
148                 {\r
149                 const PathBuffer *PB = g_PathBuffers[i];\r
150                 Bytes += PB->Size;\r
151                 }\r
152         Log("%u paths allocated, total memory %u bytes\n", g_PathBufferSize, Bytes);\r
153         }\r