public synchronized void recyclePartition(RecyclePartitionInfo recyclePartitionInfo) {
        Preconditions.checkState(!idToPartition.containsKey(recyclePartitionInfo.getPartition().getId()));

        long dbId = recyclePartitionInfo.getDbId();
        long tableId = recyclePartitionInfo.getTableId();
        Partition partition = recyclePartitionInfo.getPartition();
        long partitionId = partition.getId();
        String partitionName = partition.getName();

        disableRecoverPartitionWithSameName(dbId, tableId, partitionName);

        long recycleTime = recyclePartitionInfo.isRecoverable() ? System.currentTimeMillis() : 0;
        idToRecycleTime.put(partitionId, recycleTime);
        idToPartition.put(partitionId, recyclePartitionInfo);
        LOG.info("Finished put partition '{}' to recycle bin. dbId: {} tableId: {} partitionId: {} recoverable: {}",
                partitionName, dbId, tableId, partitionId, recyclePartitionInfo.isRecoverable());
    }
@Test
    public void testRecyclePartition(@Mocked GlobalStateMgr globalStateMgr, @Mocked EditLog editLog) {
        Partition p1 = new Partition(111, "uno", null, null);
        Partition p2SameName = new Partition(22, "dos", null, null);
        Partition p2 = new Partition(222, "dos", null, null);

        new Expectations() {
            {
                GlobalStateMgr.getCurrentState();
                minTimes = 0;
                result = globalStateMgr;
            }
        };
        new Expectations() {
            {
                globalStateMgr.getLocalMetastore().onErasePartition((Partition) any);
                minTimes = 0;

                globalStateMgr.getEditLog();
                minTimes = 0;
                result = editLog;
            }
        };
        new Expectations() {
            {
                editLog.logErasePartition(anyLong);
                minTimes = 0;
            }
        };

        // 1. add 2 partitions
        long dbId = 1;
        long tableId = 2;
        DataProperty dataProperty = new DataProperty(TStorageMedium.HDD);
        CatalogRecycleBin recycleBin = new CatalogRecycleBin();

        recycleBin.recyclePartition(new RecycleRangePartitionInfo(dbId, tableId, p1, null, dataProperty, (short) 2, false, null));
        recycleBin.recyclePartition(
                new RecycleRangePartitionInfo(dbId, tableId, p2SameName, null, dataProperty, (short) 2, false, null));
        recycleBin.recyclePartition(new RecycleRangePartitionInfo(dbId, tableId, p2, null, dataProperty, (short) 2, false, null));

        Assert.assertEquals(recycleBin.getPartition(p1.getId()), p1);
        Assert.assertEquals(recycleBin.getPartition(p2.getId()), p2);
        Assert.assertTrue(recycleBin.idToRecycleTime.containsKey(p1.getId()));
        Assert.assertTrue(recycleBin.idToRecycleTime.containsKey(p2.getId()));

        // 2. manually set table expire time & recycle table1
        Config.catalog_trash_expire_second = 3600;
        long now = System.currentTimeMillis();
        long expireFromNow = now - 3600 * 1000L;
        recycleBin.idToRecycleTime.put(p1.getId(), expireFromNow - 1000);
        recycleBin.erasePartition(now);

        Assert.assertNull(recycleBin.getPartition(p1.getId()));
        Assert.assertEquals(recycleBin.getPartition(p2.getId()), p2);

        // 3. set recyle later, check if recycle now
        CatalogRecycleBin.LATE_RECYCLE_INTERVAL_SECONDS = 10;
        Assert.assertFalse(recycleBin.ensureEraseLater(p1.getId(), now));  // already erased
        Assert.assertTrue(recycleBin.ensureEraseLater(p2.getId(), now));
        Assert.assertEquals(0, recycleBin.enableEraseLater.size());
        recycleBin.idToRecycleTime.put(p2.getId(), expireFromNow + 1000);
        Assert.assertTrue(recycleBin.ensureEraseLater(p2.getId(), now));
        Assert.assertEquals(1, recycleBin.enableEraseLater.size());
        Assert.assertTrue(recycleBin.enableEraseLater.contains(p2.getId()));

        // 4. won't erase on expire time
        recycleBin.idToRecycleTime.put(p2.getId(), expireFromNow - 1000);
        recycleBin.erasePartition(now);
        Assert.assertEquals(recycleBin.getPartition(p2.getId()), p2);
        Assert.assertEquals(1, recycleBin.idToRecycleTime.size());

        // 5. will erase after expire time + latency time
        recycleBin.idToRecycleTime.put(p2.getId(), expireFromNow - 11000);
        Assert.assertFalse(recycleBin.ensureEraseLater(p2.getId(), now));
        recycleBin.erasePartition(now);
        Assert.assertEquals(recycleBin.getPartition(p2.getId()), null);
        Assert.assertEquals(0, recycleBin.idToRecycleTime.size());
        Assert.assertEquals(0, recycleBin.enableEraseLater.size());
    }