001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hdfs.server.namenode.snapshot;
019
020import java.io.DataOutput;
021import java.io.IOException;
022import java.util.List;
023
024import org.apache.hadoop.hdfs.server.namenode.FSImageSerialization;
025import org.apache.hadoop.hdfs.server.namenode.INode;
026import org.apache.hadoop.hdfs.server.namenode.INode.BlocksMapUpdateInfo;
027import org.apache.hadoop.hdfs.server.namenode.INodeFile;
028import org.apache.hadoop.hdfs.server.namenode.INodeFileAttributes;
029import org.apache.hadoop.hdfs.server.namenode.Quota;
030import org.apache.hadoop.hdfs.server.namenode.snapshot.SnapshotFSImageFormat.ReferenceMap;
031
032/**
033 * The difference of an {@link INodeFile} between two snapshots.
034 */
035public class FileDiff extends
036    AbstractINodeDiff<INodeFile, INodeFileAttributes, FileDiff> {
037
038  /** The file size at snapshot creation time. */
039  private final long fileSize;
040
041  FileDiff(int snapshotId, INodeFile file) {
042    super(snapshotId, null, null);
043    fileSize = file.computeFileSize();
044  }
045
046  /** Constructor used by FSImage loading */
047  FileDiff(int snapshotId, INodeFileAttributes snapshotINode,
048      FileDiff posteriorDiff, long fileSize) {
049    super(snapshotId, snapshotINode, posteriorDiff);
050    this.fileSize = fileSize;
051  }
052
053  /** @return the file size in the snapshot. */
054  public long getFileSize() {
055    return fileSize;
056  }
057  
058  @Override
059  Quota.Counts combinePosteriorAndCollectBlocks(INodeFile currentINode,
060      FileDiff posterior, BlocksMapUpdateInfo collectedBlocks,
061      final List<INode> removedINodes) {
062    return currentINode.getFileWithSnapshotFeature()
063        .updateQuotaAndCollectBlocks(currentINode, posterior, collectedBlocks,
064            removedINodes);
065  }
066  
067  @Override
068  public String toString() {
069    return super.toString() + " fileSize=" + fileSize + ", rep="
070        + (snapshotINode == null? "?": snapshotINode.getFileReplication());
071  }
072
073  @Override
074  void write(DataOutput out, ReferenceMap referenceMap) throws IOException {
075    writeSnapshot(out);
076    out.writeLong(fileSize);
077
078    // write snapshotINode
079    if (snapshotINode != null) {
080      out.writeBoolean(true);
081      FSImageSerialization.writeINodeFileAttributes(snapshotINode, out);
082    } else {
083      out.writeBoolean(false);
084    }
085  }
086
087  @Override
088  Quota.Counts destroyDiffAndCollectBlocks(INodeFile currentINode,
089      BlocksMapUpdateInfo collectedBlocks, final List<INode> removedINodes) {
090    return currentINode.getFileWithSnapshotFeature()
091        .updateQuotaAndCollectBlocks(currentINode, this, collectedBlocks,
092            removedINodes);
093  }
094}