()
| 1275 | } |
| 1276 | |
| 1277 | func (db *DB) freepages() []common.Pgid { |
| 1278 | tx, err := db.beginTx() |
| 1279 | defer func() { |
| 1280 | err = tx.Rollback() |
| 1281 | if err != nil { |
| 1282 | panic("freepages: failed to rollback tx") |
| 1283 | } |
| 1284 | }() |
| 1285 | if err != nil { |
| 1286 | panic("freepages: failed to open read only tx") |
| 1287 | } |
| 1288 | |
| 1289 | reachable := make(map[common.Pgid]*common.Page) |
| 1290 | nofreed := make(map[common.Pgid]bool) |
| 1291 | ech := make(chan error) |
| 1292 | |
| 1293 | go func() { |
| 1294 | defer close(ech) |
| 1295 | tx.recursivelyCheckBucket(&tx.root, reachable, nofreed, HexKVStringer(), ech) |
| 1296 | }() |
| 1297 | // following for loop will exit once channel is closed in the above goroutine. |
| 1298 | // we don't need to wait explictly with a waitgroup |
| 1299 | for e := range ech { |
| 1300 | panic(fmt.Sprintf("freepages: failed to get all reachable pages (%v)", e)) |
| 1301 | } |
| 1302 | |
| 1303 | // TODO: If check bucket reported any corruptions (ech) we shouldn't proceed to freeing the pages. |
| 1304 | |
| 1305 | var fids []common.Pgid |
| 1306 | for i := common.Pgid(2); i < db.meta().Pgid(); i++ { |
| 1307 | if _, ok := reachable[i]; !ok { |
| 1308 | fids = append(fids, i) |
| 1309 | } |
| 1310 | } |
| 1311 | return fids |
| 1312 | } |
| 1313 | |
| 1314 | func newFreelist(freelistType FreelistType) fl.Interface { |
| 1315 | if freelistType == FreelistMapType { |
no test coverage detected