/* * Licensed to Crate under one or more contributor license agreements. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. Crate 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. * * However, if you have executed another commercial license agreement * with Crate these terms will supersede the license and you may use the * software solely pursuant to the terms of the relevant commercial * agreement. */ package io.crate.monitor; import com.google.common.collect.Iterators; import io.crate.types.DataTypes; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.lucene.BytesRefs; import java.io.IOException; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class ExtendedFsStats implements Iterable<ExtendedFsStats.Info>, Streamable { public static class Info implements Streamable { private BytesRef path; @Nullable private BytesRef dev; private long total = -1; private long free = -1; private long available = -1; private long used = -1; private long diskReads = -1; private long diskWrites = -1; private long diskReadBytes = -1; private long diskWriteBytes = -1; public static Info readInfo(StreamInput in) throws IOException { Info info = new Info(); info.readFrom(in); return info; } public Info() { } public Info(String path, @Nullable String dev, long total, long free, long available, long used, long diskReads, long diskWrites, long diskReadBytes, long diskWriteBytes) { this.path = new BytesRef(path); this.dev = BytesRefs.toBytesRef(dev); this.total = total; this.free = free; this.available = available; this.used = used; this.diskReads = diskReads; this.diskWrites = diskWrites; this.diskReadBytes = diskReadBytes; this.diskWriteBytes = diskWriteBytes; } public BytesRef path() { return path; } public void path(String path) { this.path = BytesRefs.toBytesRef(path); } @Nullable public BytesRef dev() { return dev; } public void dev(@Nullable String dev) { this.dev = BytesRefs.toBytesRef(dev); } public long total() { return total; } public void total(long total) { this.total = total; } public long free() { return free; } public void free(long free) { this.free = free; } public long available() { return available; } public void available(long available) { this.available = available; } public long used() { return used; } public void used(long used) { this.used = used; } public long diskReads() { return this.diskReads; } public void diskReads(long diskReads) { this.diskReads = diskReads; } public long diskWrites() { return this.diskWrites; } public void diskWrites(long diskWrites) { this.diskWrites = diskWrites; } public long diskReadSizeInBytes() { return diskReadBytes; } public void diskReadSizeInBytes(long diskReadBytes) { this.diskReadBytes = diskReadBytes; } public long diskWriteSizeInBytes() { return diskWriteBytes; } public void diskWriteSizeInBytes(long diskWriteBytes) { this.diskWriteBytes = diskWriteBytes; } public void add(Info info) { total = addLong(total, info.total); free = addLong(free, info.free); available = addLong(available, info.available); used = addLong(used, info.used); diskReads = addLong(diskReads, info.diskReads); diskWrites = addLong(diskWrites, info.diskWrites); diskReadBytes = addLong(diskReadBytes, info.diskReadBytes); diskWriteBytes = addLong(diskWriteBytes, info.diskWriteBytes); } private long addLong(long existing, long added) { if (existing < 0) { return added; } return existing + added; } @Override public void readFrom(StreamInput in) throws IOException { total = in.readLong(); free = in.readLong(); available = in.readLong(); used = in.readLong(); diskReads = in.readLong(); diskWrites = in.readLong(); diskReadBytes = in.readLong(); diskWriteBytes = in.readLong(); path = DataTypes.STRING.readValueFrom(in); dev = DataTypes.STRING.readValueFrom(in); } @Override public void writeTo(StreamOutput out) throws IOException { out.writeLong(total); out.writeLong(free); out.writeLong(available); out.writeLong(used); out.writeLong(diskReads); out.writeLong(diskWrites); out.writeLong(diskReadBytes); out.writeLong(diskWriteBytes); DataTypes.STRING.writeValueTo(out, path); DataTypes.STRING.writeValueTo(out, dev); } } private Info[] infos = new Info[0]; private Info total; public ExtendedFsStats() { } public ExtendedFsStats(Info total) { this.total = total; } public ExtendedFsStats(Info[] infos) { this.infos = infos; this.total = null; } public Info total() { if (total != null) { return total; } Info res = new Info(); Set<BytesRef> seenDevices = new HashSet<>(infos.length); for (Info subInfo : infos) { if (subInfo.dev != null) { if (!seenDevices.add(subInfo.dev)) { continue; // already added numbers for this device; } } res.add(subInfo); } total = res; return res; } public void total(Info total) { this.total = total; } public Info[] infos() { return infos; } public void infos(Info[] infos) { this.infos = infos; } @Override public Iterator<Info> iterator() { return Iterators.forArray(infos); } public int size() { return infos.length; } public static ExtendedFsStats readExtendedFsStats(StreamInput in) throws IOException { ExtendedFsStats stat = new ExtendedFsStats(); stat.readFrom(in); return stat; } @Override public void readFrom(StreamInput in) throws IOException { total = in.readOptionalStreamable(Info::new); infos = new Info[in.readVInt()]; for (int i = 0; i < infos.length; i++) { infos[i] = Info.readInfo(in); } } @Override public void writeTo(StreamOutput out) throws IOException { out.writeOptionalStreamable(total); out.writeVInt(infos.length); for (Info info : infos) { info.writeTo(out); } } }