| 999 | } |
| 1000 | |
| 1001 | func (s *levelsController) addLevel0Table(t *table.Table) error { |
| 1002 | // Add table to manifest file only if it is not opened in memory. We don't want to add a table |
| 1003 | // to the manifest file if it exists only in memory. |
| 1004 | if !t.IsInmemory { |
| 1005 | // We update the manifest _before_ the table becomes part of a levelHandler, because at that |
| 1006 | // point it could get used in some compaction. This ensures the manifest file gets updated in |
| 1007 | // the proper order. (That means this update happens before that of some compaction which |
| 1008 | // deletes the table.) |
| 1009 | err := s.kv.manifest.addChanges([]*pb.ManifestChange{ |
| 1010 | newCreateChange(t.ID(), 0, t.KeyID(), t.CompressionType()), |
| 1011 | }) |
| 1012 | if err != nil { |
| 1013 | return err |
| 1014 | } |
| 1015 | } |
| 1016 | |
| 1017 | for !s.levels[0].tryAddLevel0Table(t) { |
| 1018 | // Stall. Make sure all levels are healthy before we unstall. |
| 1019 | var timeStart time.Time |
| 1020 | { |
| 1021 | s.kv.opt.Debugf("STALLED STALLED STALLED: %v\n", time.Since(s.lastUnstalled)) |
| 1022 | s.cstatus.RLock() |
| 1023 | for i := 0; i < s.kv.opt.MaxLevels; i++ { |
| 1024 | s.kv.opt.Debugf("level=%d. Status=%s Size=%d\n", |
| 1025 | i, s.cstatus.levels[i].debug(), s.levels[i].getTotalSize()) |
| 1026 | } |
| 1027 | s.cstatus.RUnlock() |
| 1028 | timeStart = time.Now() |
| 1029 | } |
| 1030 | // Before we unstall, we need to make sure that level 0 is healthy. Otherwise, we |
| 1031 | // will very quickly fill up level 0 again. |
| 1032 | for i := 0; ; i++ { |
| 1033 | // It's crucial that this behavior replicates pickCompactLevels' behavior in |
| 1034 | // computing compactability in order to guarantee progress. |
| 1035 | // Break the loop once L0 has enough space to accommodate new tables. |
| 1036 | if !s.isLevel0Compactable() { |
| 1037 | break |
| 1038 | } |
| 1039 | time.Sleep(10 * time.Millisecond) |
| 1040 | if i%100 == 0 { |
| 1041 | prios := s.pickCompactLevels() |
| 1042 | s.kv.opt.Debugf("Waiting to add level 0 table. Compaction priorities: %+v\n", prios) |
| 1043 | i = 0 |
| 1044 | } |
| 1045 | } |
| 1046 | { |
| 1047 | s.kv.opt.Debugf("UNSTALLED UNSTALLED UNSTALLED: %v\n", time.Since(timeStart)) |
| 1048 | s.lastUnstalled = time.Now() |
| 1049 | } |
| 1050 | } |
| 1051 | |
| 1052 | return nil |
| 1053 | } |
| 1054 | |
| 1055 | func (s *levelsController) close() error { |
| 1056 | err := s.cleanupLevels() |