public class CountNodeW extends Object implements Cloneable, CountNode, Serializable
Modifier and Type | Class and Description |
---|---|
static interface |
CountNodeW.Runner
A routine that runs in the context of a count node.
|
Modifier and Type | Field and Description |
---|---|
(package private) static String |
CARRY_VOLUME_ORDER_CLAUSE
An SQL order clause "ORDER BY carryVolume DESC, email" that sorts (1) numerically from highest to lowest
carry count, and (2) lexically by email address.
|
static Comparator<CountNode> |
DART_SECTOR_COMPARATOR
A comparator that sorts by dart sector.
|
(package private) static String |
RECEIVE_COUNT_ORDER_CLAUSE
An SQL order clause "ORDER BY receiveVolume DESC, email" that sorts (1) numerically from highest to lowest
receive count, and (2) lexically by email address.
|
DART_SECTOR_MAX
Constructor and Description |
---|
CountNodeW(CountTable.PollView _tablePV)
Partially creates a CountNodeW with default values, for init to finish.
|
CountNodeW(CountTable.PollView _tablePV,
IDPair _person)
Creates a CountNodeW with default values.
|
CountNodeW(CountTable.PollView _tablePV,
IDPair _person,
String _bar,
String _candidateEmail,
long _carryVolume,
byte _dartSector,
long _directVoterCount,
boolean _isCast,
boolean _isCycler,
long _rank,
long _rankIndex,
long _receiveVolume,
long _time,
String xml)
Constructs a CountNodeW.
|
Modifier and Type | Method and Description |
---|---|
String |
candidateName()
Identifies the candidate selected by the
person, for whom a vote is to be cast if the person is a
voter.
|
long |
carryVolume()
The volume of received votes that flows to the
candidate node along with the cast volume.
|
(package private) CountNodeW[] |
cast()
Casts the vote if there is one, and returns the
resulting vote trace.
|
(package private) void |
castCyclic(CountNodeW[] trace)
Casts and carries down a cyclic trace that involves this node.
|
(package private) CountNodeW[] |
castSolo()
Casts the vote (if there is one) without carrying any
received votes along.
|
(package private) void |
castStraight(CountNodeW[] trace)
Casts and carries down an acyclic trace.
|
long |
castVolume()
The weight of any original vote that is actually cast for the candidate by
this node; either 0 or 1.
|
CountNodeW |
clone() |
byte |
dartSector()
The dart sector occupied by this node, if any.
|
Long |
directVoterCount()
The number of other nodes that name this node as a candidate.
|
String |
displayTitle()
The display title of the person's position, or null if there is none.
|
String |
email()
Returns person().
|
boolean |
equals(Object o)
Returns true iff the o is a count node for the same person.
|
static String |
finalRecipientOrNobody(CountNodeW[] trace,
ResourceBundle resA)
Returns the email address of the final recipient of the trace, or the localized
string for "nobody".
|
String |
getBar()
Describes any bar against the person voting in the poll.
|
String |
getCandidateEmail()
Identifies the candidate selected by the
person, for whom a vote is to be cast if the person is a
voter.
|
String |
getLocation()
The non-default location of the person's position document, or null if the
document is at the default location in the pollwiki.
|
long |
getRank()
The rank assigned to this node, with respect to votes
received.
|
long |
getRankIndex()
The unique index that is assigned to this node by order of rank, and (secondarily) email address.
|
String |
getSource()
The mnemonic of the source engine if it is not the local vote-server.
|
long |
getTime()
Specifies the time at which the person last altered the vote.
|
long |
holdVolume()
The volume of votes held.
|
(package private) void |
init(IDPair _person)
Initializes the node by identifying the person.
|
(package private) boolean |
isBarrable()
Answers whether a bar might be set.
|
(package private) static boolean |
isBarrable(String username,
ReadyDirectory readyDirectory)
Answers whether the specified person would be barrable.
|
boolean |
isBaseCandidate()
Answers whether this node is a root candidate or a cycler.
|
boolean |
isCandidate()
Answers whether this node has a voter.
|
boolean |
isCast()
Answers whether a vote of any weight (zero or one) has
actually been cast for the chosen candidate.
|
boolean |
isCycler()
Answers whether this node is voting for a voter of it's own, directly or
indirectly.
|
boolean |
isImage()
True if the source of the vote is another voting engine, false if the source is
the local vote-server.
|
boolean |
isPersonal()
Answers whether the person is actual (true), as opposed to
merely formal (false).
|
(package private) static boolean |
isPersonal(String username,
ReadyDirectory readyDirectory)
Answers whether the specified person would be personal.
|
boolean |
isRootCandidate()
Answers whether this node is a candidate who is not a voter.
|
boolean |
isVoter()
|
String |
name()
The mailish username of the person for whom this node accounts.
|
IDPair |
person()
The person for whom this node accounts.
|
long |
receiveVolume()
The volume of votes received from other nodes.
|
(package private) void |
setBar(String newBar)
Sets a bar against the person.
|
(package private) void |
setCandidateEmail(String newCandidateEmail)
Changes the candidate selected by the person.
|
(package private) void |
setDartSector(int _newSector)
Sets the dart sector occupied by this node.
|
(package private) void |
setDisplayTitle(String newDisplayTitle)
Sets the display title.
|
(package private) void |
setLocation(String newLocation)
Sets the non-default location of the person's position document.
|
(package private) void |
setRank(long newRank)
Assigns a rank to this node.
|
(package private) void |
setRankIndex(long newRankIndex)
Assigns a rank index to this node.
|
(package private) void |
setSource(String newSource)
Sets the source engine.
|
(package private) void |
setTime(long newTime)
Sets the time at which the person last altered the vote.
|
CountTable.PollView |
tablePV()
The table in which this node is stored, or null if this is a deserialized,
read-only node.
|
String |
toString()
Returns the person's email address.
|
CountNodeW[] |
trace()
Traces the route that a vote would follow if it were cast from this node, without
forcing the trace beyond uncast nodes.
|
(package private) CountNodeW[] |
trace(boolean toForce)
Traces the route that a vote would follow if it were cast from this node.
|
(package private) CountNodeW[] |
uncast()
Withdraws the vote if one was cast, and returns the resulting vote trace.
|
(package private) void |
uncastCyclic(CountNodeW[] trace)
Withdraws cast and carried votes from a cyclic trace that involves this node.
|
(package private) void |
uncastStraight(CountNodeW[] trace)
Withdraws cast and carried votes from an acyclic trace.
|
long |
voteWeight()
The weight of original votes castable for a candidate by this node; either 0 or 1.
|
(package private) void |
write()
Writes this node to the table if it has unwritten changes.
|
static final String CARRY_VOLUME_ORDER_CLAUSE
public static final Comparator<CountNode> DART_SECTOR_COMPARATOR
static final String RECEIVE_COUNT_ORDER_CLAUSE
CountNodeW(CountTable.PollView _tablePV)
tablePV()
CountNodeW(CountTable.PollView _tablePV, IDPair _person)
CountNodeW(CountTable.PollView _tablePV, IDPair _person, String _bar, String _candidateEmail, long _carryVolume, byte _dartSector, long _directVoterCount, boolean _isCast, boolean _isCycler, long _rank, long _rankIndex, long _receiveVolume, long _time, String xml) throws XMLStreamException
xml
- the XML encoding of the node's non-relational properties,
displayTitle, location and source, or null if all of them are
at default values.XMLStreamException
tablePV()
,
person()
,
getBar()
,
getCandidateEmail()
,
carryVolume()
,
dartSector()
,
directVoterCount()
,
isCast()
,
isCycler()
,
getRank()
,
getRankIndex()
,
receiveVolume()
,
getTime()
final void init(IDPair _person)
IllegalStateException
- if the person was already identified.person()
public final long carryVolume()
public final long castVolume()
carryVolume()
public static String finalRecipientOrNobody(CountNodeW[] trace, ResourceBundle resA)
resA
- a resource bundle of type application (A).public final String getBar()
VoteCastingContext.getBar()
,
isBarrable()
,
setBar(String)
final boolean isBarrable()
getBar()
static boolean isBarrable(String username, ReadyDirectory readyDirectory)
getBar()
public final String getCandidateEmail()
candidateName()
,
setCandidateEmail(String)
final void setCandidateEmail(String newCandidateEmail)
getCandidateEmail()
public final String getLocation()
setLocation(String)
,
Category:Draftfinal void setLocation(String newLocation)
getLocation()
public final long getRank()
1, 2, 2, 4, 5, 5, 5, 5, 5, 5, 5
In the example above, two candidates are tied for second place (rank 2). The bottom rank of 5 is shared by 7 people who are probably non-candidates, receiving no votes.
setRank(long)
public final long getRankIndex()
setRankIndex(long)
,
CountTable.createIndices()
final void setRankIndex(long newRankIndex)
getRankIndex()
public final String getSource()
~/votorola/in/vomir/S
, and any vote that is cast is an image.setSource(String)
,
InputStore.U.mirrorSourceDirectories(VoteServer)
final void setSource(String newSource)
getSource()
public final long getTime()
setTime(long)
,
Vote.getTime()
final void setTime(long newTime)
getTime()
public final long holdVolume()
public final boolean isCast()
uncast()
final CountNodeW[] cast() throws SQLException, XMLStreamException
IllegalStateException
- if the vote is already cast.SQLException
XMLStreamException
isCast()
final CountNodeW[] castSolo() throws SQLException, XMLStreamException
IllegalStateException
- if the vote is already cast.SQLException
XMLStreamException
isCast()
final CountNodeW[] uncast() throws SQLException, XMLStreamException
SQLException
XMLStreamException
isCast()
public final boolean isImage()
getSource()
public final boolean isPersonal()
static boolean isPersonal(String username, ReadyDirectory readyDirectory)
public final long receiveVolume()
carryVolume
,
holdVolume()
public final CountTable.PollView tablePV()
public final CountNodeW[] trace() throws SQLException, XMLStreamException
SQLException
XMLStreamException
final CountNodeW[] trace(boolean toForce) throws SQLException, XMLStreamException
toForce
- true to continue tracing beyond nodes that have yet to cast; false to end the trace at the first such node.SQLException
XMLStreamException
public final long voteWeight()
castVolume()
final void write() throws SQLException
SQLException
public final String candidateName()
candidateName
in interface CountNode
public final byte dartSector()
CountNode
A cycler has two roles for purposes of sectoring: voter and end-candidate. If the cycler is not among the top 20 of end-candidates, then she (or he) will occupy no sector in either role. Otherwise she will occupy the same sector in both roles. It is therefore possible that she (now in the role of voter) will displace a co-voting peer from a pre-occupied sector. This is the one exception to the rule of non-displacement. To illustrate, consider the cycle pictured below. If the cycle is formed by (s) casting for (c), then it is possible for one of (p) to be forced to a different dart sector.
( ) ( ) \ ( ) / \ | / \ | / | ( ) \|/ | vote flow \ ( )---(s) (p) V \ / \ / \ / \ / ( ) (c)----(p) \ / \ / ( )---( ) <---
Dart sector assignments are persisted from count to count in the voter input table. Reassignments occur at count time due to collisions from vote shifts and these are persisted individually. Where a count based on an old snapshot of the voter input is remounted, the reassignments of that count might (supposedly) clobber those of historically more recent counts. The result would be a degree of sector displacement surfacing on the next count, based on a new snapshot of the voter input. This should be corrected when voter input storage is expanded to include historical vote shifts and other changes of vote data, as sector reassignments would then be recorded in historical sequence.
Acknowledgement: Dart sectoring was first proposed by Thomas von der Elbe. See Start/Metagov 2011-April/003824.
dartSector
in interface CountNode
setDartSector(int)
final void setDartSector(int _newSector)
dartSector()
public final Long directVoterCount()
CountNode
directVoterCount
in interface CountNode
public final String displayTitle()
CountNode
displayTitle
in interface CountNode
setDisplayTitle(String)
final void setDisplayTitle(String newDisplayTitle)
displayTitle()
public final boolean isBaseCandidate()
CountNode
isBaseCandidate
in interface CountNode
public final boolean isCandidate()
CountNode
isCandidate
in interface CountNode
public final boolean isCycler()
CountNode
isCycler
in interface CountNode
public final boolean isRootCandidate()
CountNode
isRootCandidate
in interface CountNode
public final boolean isVoter()
CountNode
public String name()
CountNode
public final CountNodeW clone()
public final boolean equals(Object o)
public final String toString()
@Warning(value="non-API") final void castCyclic(CountNodeW[] trace)
Let the following denote a series of nodes N[i], where i = 0 to n-1, in two states B and C:
-> B[0] B[1] -> B[2] -> ... -> B[n-1] -- | | - - - - - - - - - - - - - - - - - - - - - - -> C[0] -> C[1] -> C[2] -> ... -> C[n-1] -- | | - - - - - - - - - - - - - - - - - - - - - -
where:
-> is the route of votes within the series proper (other votes may enter from outside the series, but their entry is not shown here) B[i] is the state of N[i] when N[0] has withheld its vote C[i] is the state of N[i] when N[0] has cast for N[1], thus causing a cyclic cascade n is the number of nodes in the trace
Given vote counts for B, calculate those for C.
(1) C[0].receive = B[0].receive
Votes received by N[0] remain constant. No vote can ever actually cycle, so the input to N[0] cannot increase when its output increases.
(2) C[i].receive = C[j].receive , for all i, j
Equation 2 is the flood rule. It states that all nodes in the cycle will receive the same volume of votes. This follows from the fact that a vote entering the cycle will travel until just before it encounters the entry node again. Therefore it will be received by all nodes. Likewise for casts originating within the cycle; they too are evenly distributed.
From 1 and 2:
(3) C[i].receive = B[0].receive , for all i
Also:
(4) C[i].hold = B[i+1].receive - B[i].receive , for i = 1...n-1
Equation 4 states: except N[0], each node will come to hold whatever the following node had received before the cycle was formed, less whatever it itself had received. In other words, a node will hold whatever its successor had introduced to the cycle. This is guaranteed because each introduced vote must stop before it actually cycles.
Known are C[i].receive (3) and C[i].hold (4), for i = 1...n-1. C[i].carry may therefore be calculated:
(5) N.hold = N.receive - N.carry C[i].carry = C[i].receive - C[i].hold , for all i
Equation 5 states that votes are conserved. Votes that are held are those received minus those carried to the candidate node. It only remains to solve for C[0].
(6) C[0].hold = B[1].receive + B[1].cast
Equation 6 is another instance of the rule (4) that a node holds whatever its successor had introduced into the cycle.
Known are C[0].hold (6) and C[0].receive (1). C[0].carry may therefore be calculated (5).
uncastCyclic(CountNodeW[])
,
theory.xht#cycle@Warning(value="non-API") final void castStraight(CountNodeW[] trace)
uncastStraight(CountNodeW[])
@Warning(value="non-API") final void uncastCyclic(CountNodeW[] trace)
-> C[0] -> C[1] -> C[2] -> ... -> C[n-1] -- | | - - - - - - - - - - - - - - - - - - - - - - -> B[0] B[1] -> B[2] -> ... -> B[n-1] -- | | - - - - - - - - - - - - - - - - - - - - - -
Given vote counts for C (when N[0] is cast and carried), calculate those for B (when N[0] is withdrawn).
(7) B[i].hold = 0 , for i = 1...n-1
Equation 7 is true because all votes cascade to B[0]. The B series has no cycle, therefore no other node holds votes.
(8) C[i].carry - B[i].carry = sum( C[j].hold ) , or B[i].carry = C[i].carry - sum( C[j].hold ) , for i = 1...n-1 , j = i+1...n-1
When N[0] was originally cast, the increase in carriage it caused at each node had to be balanced by an increase in holds among that node's successors. And there could have been no increase in carriage at N[n-1] (1). Therefore equation 8 must hold.
Known are B[i].hold (7) and B[i].carry (8), for i = 1...n-1. B[i].receive may therefore be calculated (5).
It only remains to solve for B[0]. But its vote is witheld, so there is no carriage to other nodes:
(9) B[0].carry = 0
Known are B[0].carry (9) and B[0].receive (1). So B[0].hold may be calculated (5).
castCyclic(CountNodeW[])
@Warning(value="non-API") final void uncastStraight(CountNodeW[] trace)
castStraight(CountNodeW[])