| 894 | } |
| 895 | |
| 896 | void TmpFileMgrTest::TestDirectoryLimits(bool punch_holes) { |
| 897 | // Use an allocation size where FileGroup allocates exactly this amount of scratch |
| 898 | // space. The directory limits below are set relative to this size. |
| 899 | const int64_t ALLOC_SIZE = TmpFileMgr::HOLE_PUNCH_BLOCK_SIZE_BYTES; |
| 900 | vector<string> tmp_dirs({"/tmp/tmp-file-mgr-test.1", "/tmp/tmp-file-mgr-test.2", |
| 901 | "/tmp/tmp-file-mgr-test.3"}); |
| 902 | vector<string> tmp_dir_specs({"/tmp/tmp-file-mgr-test.1:4k", |
| 903 | "/tmp/tmp-file-mgr-test.2:8k", "/tmp/tmp-file-mgr-test.3"}); |
| 904 | RemoveAndCreateDirs(tmp_dirs); |
| 905 | TmpFileMgr tmp_file_mgr; |
| 906 | ASSERT_OK( |
| 907 | tmp_file_mgr.InitCustom(tmp_dir_specs, false, "", punch_holes, metrics_.get())); |
| 908 | |
| 909 | TmpFileGroup file_group_1( |
| 910 | &tmp_file_mgr, io_mgr(), RuntimeProfile::Create(&obj_pool_, "p1"), TUniqueId()); |
| 911 | TmpFileGroup file_group_2( |
| 912 | &tmp_file_mgr, io_mgr(), RuntimeProfile::Create(&obj_pool_, "p2"), TUniqueId()); |
| 913 | |
| 914 | vector<TmpFile*> files; |
| 915 | ASSERT_OK(CreateFiles(&file_group_1, &files)); |
| 916 | ASSERT_OK(CreateFiles(&file_group_2, &files)); |
| 917 | |
| 918 | IntGauge* dir1_usage = metrics_->FindMetricForTesting<IntGauge>( |
| 919 | "tmp-file-mgr.scratch-space-bytes-used.dir-0"); |
| 920 | IntGauge* dir2_usage = metrics_->FindMetricForTesting<IntGauge>( |
| 921 | "tmp-file-mgr.scratch-space-bytes-used.dir-1"); |
| 922 | IntGauge* dir3_usage = metrics_->FindMetricForTesting<IntGauge>( |
| 923 | "tmp-file-mgr.scratch-space-bytes-used.dir-2"); |
| 924 | |
| 925 | int64_t offset; |
| 926 | TmpFile* alloc_file; |
| 927 | |
| 928 | // Allocate three times - once per directory. We expect these allocations to go through |
| 929 | // so we should have one allocation in each directory. |
| 930 | SetNextAllocationIndex(&file_group_1, DEFAULT_PRIORITY, 0); |
| 931 | for (int i = 0; i < tmp_dir_specs.size(); ++i) { |
| 932 | ASSERT_OK(GroupAllocateSpace(&file_group_1, ALLOC_SIZE, &alloc_file, &offset)); |
| 933 | } |
| 934 | EXPECT_EQ(ALLOC_SIZE, dir1_usage->GetValue()); |
| 935 | EXPECT_EQ(ALLOC_SIZE, dir2_usage->GetValue()); |
| 936 | EXPECT_EQ(ALLOC_SIZE, dir3_usage->GetValue()); |
| 937 | |
| 938 | // This time we should hit the limit on the first directory. Do this from a |
| 939 | // different file group to show that limits are enforced across file groups. |
| 940 | for (int i = 0; i < 2; ++i) { |
| 941 | ASSERT_OK(GroupAllocateSpace(&file_group_2, ALLOC_SIZE, &alloc_file, &offset)); |
| 942 | } |
| 943 | EXPECT_EQ(ALLOC_SIZE, dir1_usage->GetValue()); |
| 944 | EXPECT_EQ(2 * ALLOC_SIZE, dir2_usage->GetValue()); |
| 945 | EXPECT_EQ(2 * ALLOC_SIZE, dir3_usage->GetValue()); |
| 946 | |
| 947 | // Now we're at the limits on two directories, all allocations should got to the |
| 948 | // last directory without a limit. |
| 949 | for (int i = 0; i < 100; ++i) { |
| 950 | ASSERT_OK(GroupAllocateSpace(&file_group_2, ALLOC_SIZE, &alloc_file, &offset)); |
| 951 | } |
| 952 | EXPECT_EQ(ALLOC_SIZE, dir1_usage->GetValue()); |
| 953 | EXPECT_EQ(2 * ALLOC_SIZE, dir2_usage->GetValue()); |