00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <repos/ConnectionCache.hxx>
00042 #include <util/avl.hxx>
00043
00044 ConnectionCache ConnectionCache::theCache;
00045
00046 #ifdef NEED_CONVERT
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #if 0
00066 typedef struct ConnectNode ConnectNode;
00067 struct ConnectNode {
00068 AvlNode avl;
00069 const char *uri;
00070 Repository *wrapped;
00071 Repository *unwrapped;
00072 };
00073
00074 struct ConnectionCache {
00075 AvlTree *tree;
00076 };
00077 #endif
00078
00079
00080 static int
00081 cnode_uri_cmp(AvlNode *n1, AvlNode *n2)
00082 {
00083 ConnectNode *cn1 = (ConnectNode *)n1;
00084 ConnectNode *cn2 = (ConnectNode *)n2;
00085
00086
00087
00088
00089 return strcmp(cn1->uri, cn2->uri);
00090 }
00091
00092 ConnectionCache *
00093 ccache_create(void)
00094 {
00095 ConnectionCache *cache = GC_MALLOC(sizeof(ConnectionCache));
00096 cache->tree = avl_create(cnode_uri_cmp, gc_malloc);
00097
00098 return cache;
00099 }
00100
00101 static ConnectNode *
00102 ccache_lookup(ConnectionCache *c, URI *uri)
00103 {
00104 ConnectNode cn;
00105 ConnectNode *retNode;
00106 AvlNode *node = NULL;
00107
00108 memset(&cn, 0, sizeof(cn));
00109 cn.uri = uri_toString(uri);
00110
00111
00112
00113 node = avl_lookupGLE(c->tree, (AvlNode *)(&cn));
00114 if (node == NULL)
00115 return NULL;
00116
00117
00118
00119
00120
00121 retNode = (ConnectNode *)node;
00122 if (path_isprefix(retNode->uri, cn.uri))
00123 return retNode;
00124
00125
00126 return NULL;
00127 }
00128
00129 static void
00130 ccache_insert(ConnectionCache *c, URI *key,
00131 Repository *wrapped, Repository *unwrapped)
00132 {
00133 ConnectNode *exists = ccache_lookup(c, key);
00134
00135 if (exists)
00136 return;
00137
00138 {
00139 ConnectNode *newNode = GC_NEW(ConnectNode);
00140
00141 newNode->uri = uri_toString(key);
00142 newNode->wrapped = wrapped;
00143 newNode->unwrapped = unwrapped;
00144 avl_insert(c->tree, (AvlNode *)newNode);
00145 }
00146 }
00147
00148
00149
00150 static int
00151 ccache_disconnect(AvlNode *node)
00152 {
00153 ConnectNode *cd = (ConnectNode *)node;
00154
00155
00156
00157
00158
00159 TRY {
00160 if (cd->wrapped)
00161 repos_Disconnect(cd->wrapped);
00162 else
00163 repos_Disconnect(cd->unwrapped);
00164 }
00165 DEFAULT(AnyException) {
00166 }
00167 END_CATCH;
00168
00169 return 0;
00170 }
00171
00172 void
00173 ccache_destroy(ConnectionCache *c)
00174 {
00175 if (c) {
00176
00177
00178 avl_iterate(c->tree, ccache_disconnect);
00179
00180
00181 c = NULL;
00182 }
00183 }
00184 #endif
00185
00186 GCPtr<Repository>
00187 ConnectionCache::doGetRepository(GCPtr<URI> uri)
00188 {
00189 assert(false);
00190 }
00191
00192 GCPtr<Repository>
00193 ConnectionCache::doGetUnwrappedRepository(GCPtr<URI> uri)
00194 {
00195 assert(false);
00196 }
00197
00198 #ifdef NEED_CONVERT
00199
00200
00201
00202
00203
00204
00205 Repository *
00206 ccache_get_repository(ConnectionCache *c, URI *uri)
00207 {
00208 URI *key = NULL;
00209
00210 if (!c)
00211 THROW(ExNullArg, format("NULL connection cache encountered."));
00212
00213
00214 ConnectNode *cnode = ccache_lookup(c, uri);
00215 if (cnode == NULL) {
00216
00217
00218 Repository *wrapped = NULL;
00219 Repository *unwrapped = repository_open(uri);
00220 repos_Connect(unwrapped);
00221
00222
00223
00224 if (REPOS_NEEDS_AUTHWRAP(unwrapped))
00225 wrapped = authrepository_wrap(unwrapped);
00226
00227 if (REPOS_IS_REMOTE(unwrapped))
00228 wrapped = cacherepository_wrap(unwrapped);
00229
00230 if (wrapped)
00231 key = wrapped->uri;
00232 else
00233 key = unwrapped->uri;
00234
00235 ccache_insert(c, key, wrapped, unwrapped);
00236
00237 return wrapped ? wrapped : unwrapped;
00238 }
00239 else {
00240 if (cnode->wrapped == NULL)
00241 return cnode->unwrapped;
00242 else
00243 return cnode->wrapped;
00244 }
00245
00246 THROW(ExNoObject, format("Couldn't get repository for \"%s\".", uri->URI));
00247
00248 return NULL;
00249 }
00250
00251
00252
00253
00254
00255 Repository *
00256 ccache_get_unwrapped_repository(ConnectionCache *c, URI *uri)
00257 {
00258
00259 ConnectNode *cnode = ccache_lookup(c, uri);
00260 if (cnode == NULL) {
00261
00262
00263 Repository *unwrapped = repository_open(uri);
00264 repos_Connect(unwrapped);
00265
00266
00267 ccache_insert(c, unwrapped->uri, NULL, unwrapped);
00268 return unwrapped;
00269 }
00270 else {
00271 return cnode->unwrapped;
00272 }
00273
00274 THROW(ExNoObject, format("Couldn't get repository for \"%s\".", uri->URI));
00275
00276 return NULL;
00277 }
00278
00279 #endif