/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.jafka.log; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; /** * the log segments(all readable messages and the last writeable file) * * @author adyliu (imxylz@gmail.com) * @since 1.0 */ public class SegmentList { private final AtomicReference<List<LogSegment>> contents; private final String name; /** * create the messages segments * * @param name the message topic name * @param segments exist segments */ public SegmentList(final String name, List<LogSegment> segments) { this.name = name; contents = new AtomicReference<List<LogSegment>>(segments); } /** * Append the given item to the end of the list * @param segment segment to append */ public void append(LogSegment segment) { while (true) { List<LogSegment> curr = contents.get(); List<LogSegment> updated = new ArrayList<LogSegment>(curr); updated.add(segment); if (contents.compareAndSet(curr, updated)) { return; } } } /** * Delete the first n items from the list * * @param newStart the logsegment who's index smaller than newStart will be deleted. * @return the deleted segment */ public List<LogSegment> trunc(int newStart) { if (newStart < 0) { throw new IllegalArgumentException("Starting index must be positive."); } while (true) { List<LogSegment> curr = contents.get(); int newLength = Math.max(curr.size() - newStart, 0); List<LogSegment> updatedList = new ArrayList<LogSegment>(curr.subList(Math.min(newStart, curr.size() - 1), curr.size())); if (contents.compareAndSet(curr, updatedList)) { return curr.subList(0, curr.size() - newLength); } } } /** * get the last segment at the moment * * @return the last segment */ public LogSegment getLastView() { List<LogSegment> views = getView(); return views.get(views.size() - 1); } /** * get all segments at the moment * * @return all segments */ public List<LogSegment> getView() { return contents.get(); } @Override public String toString() { return "[" + name + "] " + getView(); } }