@@ -245,140 +245,142 @@ class CAddrMan
245
245
void Connected_ (const CService &addr, int64_t nTime);
246
246
247
247
public:
248
+ // serialized format:
249
+ // * version byte (currently 0)
250
+ // * nKey
251
+ // * nNew
252
+ // * nTried
253
+ // * number of "new" buckets
254
+ // * all nNew addrinfos in vvNew
255
+ // * all nTried addrinfos in vvTried
256
+ // * for each bucket:
257
+ // * number of elements
258
+ // * for each element: index
259
+ //
260
+ // Notice that vvTried, mapAddr and vVector are never encoded explicitly;
261
+ // they are instead reconstructed from the other information.
262
+ //
263
+ // vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change,
264
+ // otherwise it is reconstructed as well.
265
+ //
266
+ // This format is more complex, but significantly smaller (at most 1.5 MiB), and supports
267
+ // changes to the ADDRMAN_ parameters without breaking the on-disk structure.
268
+ //
269
+ // We don't use IMPLEMENT_SERIALIZE since the serialization and deserialization code has
270
+ // very little in common.
271
+ template <typename Stream>
272
+ void Serialize (Stream &s, int nType, int nVersionDummy) const
273
+ {
274
+ LOCK (cs);
275
+
276
+ unsigned char nVersion = 0 ;
277
+ s << nVersion;
278
+ s << nKey;
279
+ s << nNew;
280
+ s << nTried;
281
+
282
+ int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT;
283
+ s << nUBuckets;
284
+ std::map<int , int > mapUnkIds;
285
+ int nIds = 0 ;
286
+ for (std::map<int , CAddrInfo>::const_iterator it = mapInfo.begin (); it != mapInfo.end (); it++) {
287
+ if (nIds == nNew) break ; // this means nNew was wrong, oh ow
288
+ mapUnkIds[(*it).first ] = nIds;
289
+ const CAddrInfo &info = (*it).second ;
290
+ if (info.nRefCount ) {
291
+ s << info;
292
+ nIds++;
293
+ }
294
+ }
295
+ nIds = 0 ;
296
+ for (std::map<int , CAddrInfo>::const_iterator it = mapInfo.begin (); it != mapInfo.end (); it++) {
297
+ if (nIds == nTried) break ; // this means nTried was wrong, oh ow
298
+ const CAddrInfo &info = (*it).second ;
299
+ if (info.fInTried ) {
300
+ s << info;
301
+ nIds++;
302
+ }
303
+ }
304
+ for (std::vector<std::set<int > >::const_iterator it = vvNew.begin (); it != vvNew.end (); it++) {
305
+ const std::set<int > &vNew = (*it);
306
+ int nSize = vNew.size ();
307
+ s << nSize;
308
+ for (std::set<int >::const_iterator it2 = vNew.begin (); it2 != vNew.end (); it2++) {
309
+ int nIndex = mapUnkIds[*it2];
310
+ s << nIndex;
311
+ }
312
+ }
313
+ }
248
314
249
- IMPLEMENT_SERIALIZE
250
- (({
251
- // serialized format:
252
- // * version byte (currently 0)
253
- // * nKey
254
- // * nNew
255
- // * nTried
256
- // * number of "new" buckets
257
- // * all nNew addrinfos in vvNew
258
- // * all nTried addrinfos in vvTried
259
- // * for each bucket:
260
- // * number of elements
261
- // * for each element: index
262
- //
263
- // Notice that vvTried, mapAddr and vVector are never encoded explicitly;
264
- // they are instead reconstructed from the other information.
265
- //
266
- // vvNew is serialized, but only used if ADDRMAN_UNKOWN_BUCKET_COUNT didn't change,
267
- // otherwise it is reconstructed as well.
268
- //
269
- // This format is more complex, but significantly smaller (at most 1.5 MiB), and supports
270
- // changes to the ADDRMAN_ parameters without breaking the on-disk structure.
271
- {
272
- LOCK (cs);
273
- unsigned char nVersion = 0 ;
274
- READWRITE (nVersion);
275
- READWRITE (nKey);
276
- READWRITE (nNew);
277
- READWRITE (nTried);
278
-
279
- CAddrMan *am = const_cast <CAddrMan*>(this );
280
- if (fWrite )
281
- {
282
- int nUBuckets = ADDRMAN_NEW_BUCKET_COUNT;
283
- READWRITE (nUBuckets);
284
- std::map<int , int > mapUnkIds;
285
- int nIds = 0 ;
286
- for (std::map<int , CAddrInfo>::iterator it = am->mapInfo .begin (); it != am->mapInfo .end (); it++)
287
- {
288
- if (nIds == nNew) break ; // this means nNew was wrong, oh ow
289
- mapUnkIds[(*it).first ] = nIds;
290
- CAddrInfo &info = (*it).second ;
291
- if (info.nRefCount )
292
- {
293
- READWRITE (info);
294
- nIds++;
295
- }
296
- }
297
- nIds = 0 ;
298
- for (std::map<int , CAddrInfo>::iterator it = am->mapInfo .begin (); it != am->mapInfo .end (); it++)
299
- {
300
- if (nIds == nTried) break ; // this means nTried was wrong, oh ow
301
- CAddrInfo &info = (*it).second ;
302
- if (info.fInTried )
303
- {
304
- READWRITE (info);
305
- nIds++;
306
- }
307
- }
308
- for (std::vector<std::set<int > >::iterator it = am->vvNew .begin (); it != am->vvNew .end (); it++)
309
- {
310
- const std::set<int > &vNew = (*it);
311
- int nSize = vNew.size ();
312
- READWRITE (nSize);
313
- for (std::set<int >::iterator it2 = vNew.begin (); it2 != vNew.end (); it2++)
314
- {
315
- int nIndex = mapUnkIds[*it2];
316
- READWRITE (nIndex);
317
- }
318
- }
315
+ template <typename Stream>
316
+ void Unserialize (Stream& s, int nType, int nVersionDummy)
317
+ {
318
+ LOCK (cs);
319
+
320
+ unsigned char nVersion;
321
+ s >> nVersion;
322
+ s >> nKey;
323
+ s >> nNew;
324
+ s >> nTried;
325
+
326
+ int nUBuckets = 0 ;
327
+ s >> nUBuckets;
328
+ nIdCount = 0 ;
329
+ mapInfo.clear ();
330
+ mapAddr.clear ();
331
+ vRandom.clear ();
332
+ vvTried = std::vector<std::vector<int > >(ADDRMAN_TRIED_BUCKET_COUNT, std::vector<int >(0 ));
333
+ vvNew = std::vector<std::set<int > >(ADDRMAN_NEW_BUCKET_COUNT, std::set<int >());
334
+ for (int n = 0 ; n < nNew; n++) {
335
+ CAddrInfo &info = mapInfo[n];
336
+ s >> info;
337
+ mapAddr[info] = n;
338
+ info.nRandomPos = vRandom.size ();
339
+ vRandom.push_back (n);
340
+ if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT) {
341
+ vvNew[info.GetNewBucket (nKey)].insert (n);
342
+ info.nRefCount ++;
343
+ }
344
+ }
345
+ nIdCount = nNew;
346
+ int nLost = 0 ;
347
+ for (int n = 0 ; n < nTried; n++) {
348
+ CAddrInfo info;
349
+ s >> info;
350
+ std::vector<int > &vTried = vvTried[info.GetTriedBucket (nKey)];
351
+ if (vTried.size () < ADDRMAN_TRIED_BUCKET_SIZE) {
352
+ info.nRandomPos = vRandom.size ();
353
+ info.fInTried = true ;
354
+ vRandom.push_back (nIdCount);
355
+ mapInfo[nIdCount] = info;
356
+ mapAddr[info] = nIdCount;
357
+ vTried.push_back (nIdCount);
358
+ nIdCount++;
319
359
} else {
320
- int nUBuckets = 0 ;
321
- READWRITE (nUBuckets);
322
- am->nIdCount = 0 ;
323
- am->mapInfo .clear ();
324
- am->mapAddr .clear ();
325
- am->vRandom .clear ();
326
- am->vvTried = std::vector<std::vector<int > >(ADDRMAN_TRIED_BUCKET_COUNT, std::vector<int >(0 ));
327
- am->vvNew = std::vector<std::set<int > >(ADDRMAN_NEW_BUCKET_COUNT, std::set<int >());
328
- for (int n = 0 ; n < am->nNew ; n++)
329
- {
330
- CAddrInfo &info = am->mapInfo [n];
331
- READWRITE (info);
332
- am->mapAddr [info] = n;
333
- info.nRandomPos = vRandom.size ();
334
- am->vRandom .push_back (n);
335
- if (nUBuckets != ADDRMAN_NEW_BUCKET_COUNT)
336
- {
337
- am->vvNew [info.GetNewBucket (am->nKey )].insert (n);
338
- info.nRefCount ++;
339
- }
340
- }
341
- am->nIdCount = am->nNew ;
342
- int nLost = 0 ;
343
- for (int n = 0 ; n < am->nTried ; n++)
344
- {
345
- CAddrInfo info;
346
- READWRITE (info);
347
- std::vector<int > &vTried = am->vvTried [info.GetTriedBucket (am->nKey )];
348
- if (vTried.size () < ADDRMAN_TRIED_BUCKET_SIZE)
349
- {
350
- info.nRandomPos = vRandom.size ();
351
- info.fInTried = true ;
352
- am->vRandom .push_back (am->nIdCount );
353
- am->mapInfo [am->nIdCount ] = info;
354
- am->mapAddr [info] = am->nIdCount ;
355
- vTried.push_back (am->nIdCount );
356
- am->nIdCount ++;
357
- } else {
358
- nLost++;
359
- }
360
- }
361
- am->nTried -= nLost;
362
- for (int b = 0 ; b < nUBuckets; b++)
363
- {
364
- std::set<int > &vNew = am->vvNew [b];
365
- int nSize = 0 ;
366
- READWRITE (nSize);
367
- for (int n = 0 ; n < nSize; n++)
368
- {
369
- int nIndex = 0 ;
370
- READWRITE (nIndex);
371
- CAddrInfo &info = am->mapInfo [nIndex];
372
- if (nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS)
373
- {
374
- info.nRefCount ++;
375
- vNew.insert (nIndex);
376
- }
377
- }
360
+ nLost++;
361
+ }
362
+ }
363
+ nTried -= nLost;
364
+ for (int b = 0 ; b < nUBuckets; b++) {
365
+ std::set<int > &vNew = vvNew[b];
366
+ int nSize = 0 ;
367
+ s >> nSize;
368
+ for (int n = 0 ; n < nSize; n++) {
369
+ int nIndex = 0 ;
370
+ s >> nIndex;
371
+ CAddrInfo &info = mapInfo[nIndex];
372
+ if (nUBuckets == ADDRMAN_NEW_BUCKET_COUNT && info.nRefCount < ADDRMAN_NEW_BUCKETS_PER_ADDRESS) {
373
+ info.nRefCount ++;
374
+ vNew.insert (nIndex);
378
375
}
379
376
}
380
377
}
381
- });)
378
+ }
379
+
380
+ unsigned int GetSerializeSize (int nType, int nVersion) const
381
+ {
382
+ return (CSizeComputer (nType, nVersion) << *this ).size ();
383
+ }
382
384
383
385
CAddrMan () : vRandom(0 ), vvTried(ADDRMAN_TRIED_BUCKET_COUNT, std::vector<int >(0 )), vvNew(ADDRMAN_NEW_BUCKET_COUNT, std::set<int >())
384
386
{
0 commit comments