From 7b84eb10c7c70dc83acd21afcc1ae631369428eb Mon Sep 17 00:00:00 2001 From: "@syxhe" Date: Wed, 1 Oct 2025 21:26:08 -0500 Subject: Implement ChannelNode --- src/main/java/ChannelNode.java | 153 ++++++++++++++++++++++++++++++++++++++++ src/main/java/IChannelNode.java | 14 ++-- 2 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 src/main/java/ChannelNode.java (limited to 'src/main/java') diff --git a/src/main/java/ChannelNode.java b/src/main/java/ChannelNode.java new file mode 100644 index 0000000..e984cf0 --- /dev/null +++ b/src/main/java/ChannelNode.java @@ -0,0 +1,153 @@ +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +public class ChannelNode implements IChannelNode { + private Map incoming; + private Map outgoing; + + public ChannelNode() { + incoming = new TreeMap<>(); + outgoing = new TreeMap<>(); + } + + @Override + public void setConnections(Map conmap, Direction dir) throws IllegalArgumentException { + if(conmap == null) throw new IllegalArgumentException("connection map is null"); + if(dir == null) throw new IllegalArgumentException("direction is null"); + if(conmap.containsKey(this)) throw new IllegalArgumentException("connection map contains this node"); + + int dv = dir.getVal(); + if(dv >= Direction.INCOMING.getVal()) incoming = conmap; + if(dv >= Direction.OUTGOING.getVal()) outgoing = conmap; + } + + @Override + public void setNumConnections(IChannelNode node, Direction dir, int num) throws IllegalArgumentException { + if(node == null) throw new IllegalArgumentException("node is null"); + if(dir == null) throw new IllegalArgumentException("dir is null"); + if(num < 0) throw new IllegalArgumentException("num < 0"); + + int dv = dir.getVal(); + if(dv >= Direction.INCOMING.getVal()) incoming.put(node, num); + if(dv >= Direction.OUTGOING.getVal()) outgoing.put(node, num); + } + + @Override + public void addConnection(IChannelNode node, Direction dir) { + if(node == null) throw new IllegalArgumentException("node is null"); + if(node == this) throw new IllegalArgumentException("node is self"); + if(dir == null) throw new IllegalStateException("dir is null"); + + int dv = dir.getVal(); + if(dv >= Direction.INCOMING.getVal()) incoming.put(node, incoming.get(node) + 1); + if(dv >= Direction.OUTGOING.getVal()) outgoing.put(node, outgoing.get(node) + 1); + } + + @Override + public void addConnections(Iterable nodes, Direction dir) { + if(nodes == null) throw new IllegalArgumentException("node is null"); + if(dir == null) throw new IllegalArgumentException("dir is null"); + nodes.forEach((node) -> {if(node == this) throw new IllegalArgumentException("one of the included nodes is this node");}); + + int dv = dir.getVal(), + incomingV = Direction.INCOMING.getVal(), + outgoingV = Direction.OUTGOING.getVal(); + + nodes.forEach((node) -> { + if(dv >= incomingV) incoming.put(node, incoming.get(node) + 1); + if(dv >= outgoingV) outgoing.put(node, outgoing.get(node) + 1); + }); + } + + @Override + public void removeConnection(IChannelNode node, Direction dir) { + if(node == null) throw new IllegalArgumentException("node is null"); + if(node == this) throw new IllegalArgumentException("node is self"); + if(dir == null) throw new IllegalStateException("dir is null"); + + int dv = dir.getVal(); + if(dv >= Direction.INCOMING.getVal()) incoming.put(node, Math.max(incoming.get(node) - 1, 0)); + if(dv >= Direction.OUTGOING.getVal()) outgoing.put(node, Math.max(outgoing.get(node) - 1, 0)); + } + + @Override + public void removeConnections(Iterable nodes, Direction dir) { + if(nodes == null) throw new IllegalArgumentException("node is null"); + if(dir == null) throw new IllegalArgumentException("dir is null"); + nodes.forEach((node) -> {if(node == this) throw new IllegalArgumentException("one of the included nodes is this node");}); + + int dv = dir.getVal(), + incomingV = Direction.INCOMING.getVal(), + outgoingV = Direction.OUTGOING.getVal(); + + nodes.forEach((node) -> { + if(dv >= incomingV) incoming.put(node, Math.max(incoming.get(node) - 1, 0)); + if(dv >= outgoingV) outgoing.put(node, Math.max(outgoing.get(node) - 1, 0)); + }); + } + + @Override + public void clearConnections(Direction dir) { + if(dir == null) throw new IllegalArgumentException("dir is null"); + + int dv = dir.getVal(); + if(dv >= Direction.INCOMING.getVal()) incoming.clear(); + if(dv >= Direction.OUTGOING.getVal()) outgoing.clear(); + } + + @Override + public boolean connectionExists(IChannelNode node, Direction dir) { + if(node == null) throw new IllegalArgumentException("node is null"); + if(dir == null) throw new IllegalArgumentException("dir is null"); + + switch (dir) { + case INCOMING -> {return incoming.containsKey(node);} + case OUTGOING -> {return outgoing.containsKey(node);} + case BOTH -> {return (incoming.containsKey(node) && outgoing.containsKey(node));} + default -> throw new IllegalStateException("got unknown direction"); + } + } + + @Override + public int getNumConnections(Direction dir) { + int total = 0; + int dv = dir.getVal(); + + if(dv >= Direction.INCOMING.getVal()) for(int i: incoming.values()) total += i; + if(dv >= Direction.OUTGOING.getVal()) for(int i: outgoing.values()) total += i; + return total; + } + + @Override + public Map getIncomingConnections() { + return incoming; + } + + @Override + public Map getOutgoingConnections() { + return outgoing; + } + + @Override + public List> getConnections(Direction dir) { + if(dir == null) throw new IllegalArgumentException("dir is null"); + + int dv = dir.getVal(); + ArrayList> res = new ArrayList<>(); + if(dv >= Direction.INCOMING.getVal()) res.add(incoming); + if(dv >= Direction.OUTGOING.getVal()) res.add(outgoing); + + return res; + } + + @Override + public int compareTo(IChannelNode iChannelNode) { + if(iChannelNode == null) throw new IllegalArgumentException("comparison node is null"); + int selfTotal = getNumConnections(Direction.BOTH), + theirTotal = iChannelNode.getNumConnections(Direction.BOTH); + + return selfTotal - theirTotal; + } +} diff --git a/src/main/java/IChannelNode.java b/src/main/java/IChannelNode.java index 463f3ac..baf7572 100644 --- a/src/main/java/IChannelNode.java +++ b/src/main/java/IChannelNode.java @@ -1,14 +1,19 @@ import java.util.List; import java.util.Map; -public interface IChannelNode { +public interface IChannelNode extends Comparable { enum Direction { - INCOMING, - OUTGOING, - BOTH + INCOMING(0), // Users incoming from outside channel (aka: other channel forwarded this channel's post) + OUTGOING(1), // Users outgoing from this channel (aka: this channel forwarded someone else's post) + BOTH(2); // Modify both incoming and outgoing counts at once + + private final int val; + Direction(int val) {this.val = val;} + public int getVal() {return this.val;} } void setConnections(Map conmap, Direction dir); + void setNumConnections(IChannelNode node, Direction dir, int num); void addConnection(IChannelNode node, Direction dir); void addConnections(Iterable nodes, Direction dir); void removeConnection(IChannelNode node, Direction dir); @@ -16,6 +21,7 @@ public interface IChannelNode { void clearConnections(Direction dir); boolean connectionExists(IChannelNode node, Direction dir); + int getNumConnections(Direction dir); Map getIncomingConnections(); Map getOutgoingConnections(); List> getConnections(Direction dir); -- cgit v1.2.3