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