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 */ 018 package org.apache.hadoop.hdfs.server.protocol; 019 020 import java.io.DataInput; 021 import java.io.DataOutput; 022 import java.io.IOException; 023 import java.util.Collections; 024 import java.util.List; 025 026 import org.apache.hadoop.io.Writable; 027 028 import com.google.common.base.Joiner; 029 import com.google.common.base.Preconditions; 030 import com.google.common.collect.Lists; 031 032 /** 033 * An enumeration of logs available on a remote NameNode. 034 */ 035 public class RemoteEditLogManifest implements Writable { 036 037 private List<RemoteEditLog> logs; 038 039 public RemoteEditLogManifest() { 040 } 041 042 public RemoteEditLogManifest(List<RemoteEditLog> logs) { 043 this.logs = logs; 044 checkState(); 045 } 046 047 048 /** 049 * Check that the logs are contiguous and non-overlapping 050 * sequences of transactions, in sorted order 051 * @throws IllegalStateException if incorrect 052 */ 053 private void checkState() { 054 Preconditions.checkNotNull(logs); 055 056 RemoteEditLog prev = null; 057 for (RemoteEditLog log : logs) { 058 if (prev != null) { 059 if (log.getStartTxId() != prev.getEndTxId() + 1) { 060 throw new IllegalStateException("Invalid log manifest:" + this); 061 } 062 } 063 064 prev = log; 065 } 066 } 067 068 public List<RemoteEditLog> getLogs() { 069 return Collections.unmodifiableList(logs); 070 } 071 072 073 074 @Override 075 public String toString() { 076 return "[" + Joiner.on(", ").join(logs) + "]"; 077 } 078 079 080 @Override 081 public void write(DataOutput out) throws IOException { 082 out.writeInt(logs.size()); 083 for (RemoteEditLog log : logs) { 084 log.write(out); 085 } 086 } 087 088 @Override 089 public void readFields(DataInput in) throws IOException { 090 int numLogs = in.readInt(); 091 logs = Lists.newArrayList(); 092 for (int i = 0; i < numLogs; i++) { 093 RemoteEditLog log = new RemoteEditLog(); 094 log.readFields(in); 095 logs.add(log); 096 } 097 checkState(); 098 } 099 }