···1718 // Binary format constants
19 DIDINDEX_MAGIC = "PLCD"
20- DIDINDEX_VERSION = 3
00002122 BUILD_BATCH_SIZE = 100 // Process 100 bundles at a time
23···63 LastBundle int `json:"last_bundle"`
64}
6566-// OpLocation represents exact location of an operation
67-type OpLocation struct {
68- Bundle uint16
69- Position uint16
70- Nullified bool
71-}
72-73// ShardBuilder accumulates DID positions for a shard
74type ShardBuilder struct {
75 entries map[string][]OpLocation
76 mu sync.Mutex
77}
7800079// OpLocationWithOperation contains an operation with its bundle/position
80type OpLocationWithOperation struct {
81 Operation plcclient.PLCOperation
82 Bundle int
83 Position int
84}
00000000000000000000000000000000000000000000000000000000000
···1718 // Binary format constants
19 DIDINDEX_MAGIC = "PLCD"
20+ DIDINDEX_VERSION = 4
21+22+ // Format sizes
23+ LOCATION_SIZE_V3 = 5 // Old: 2+2+1
24+ LOCATION_SIZE_V4 = 4 // New: packed uint32
2526 BUILD_BATCH_SIZE = 100 // Process 100 bundles at a time
27···67 LastBundle int `json:"last_bundle"`
68}
69000000070// ShardBuilder accumulates DID positions for a shard
71type ShardBuilder struct {
72 entries map[string][]OpLocation
73 mu sync.Mutex
74}
7576+// OpLocation represents exact location of an operation
77+type OpLocation uint32
78+79// OpLocationWithOperation contains an operation with its bundle/position
80type OpLocationWithOperation struct {
81 Operation plcclient.PLCOperation
82 Bundle int
83 Position int
84}
85+86+func NewOpLocation(bundle, position uint16, nullified bool) OpLocation {
87+ globalPos := uint32(bundle)*10000 + uint32(position)
88+ loc := globalPos << 1
89+ if nullified {
90+ loc |= 1
91+ }
92+ return OpLocation(loc)
93+}
94+95+// Getters
96+func (loc OpLocation) GlobalPosition() uint32 {
97+ return uint32(loc) >> 1
98+}
99+100+func (loc OpLocation) Bundle() uint16 {
101+ return uint16(loc.GlobalPosition() / 10000)
102+}
103+104+func (loc OpLocation) Position() uint16 {
105+ return uint16(loc.GlobalPosition() % 10000)
106+}
107+108+func (loc OpLocation) Nullified() bool {
109+ return (loc & 1) == 1
110+}
111+112+func (loc OpLocation) IsAfter(other OpLocation) bool {
113+ // Compare global positions directly
114+ return loc.GlobalPosition() > other.GlobalPosition()
115+}
116+117+func (loc OpLocation) IsBefore(other OpLocation) bool {
118+ return loc.GlobalPosition() < other.GlobalPosition()
119+}
120+121+func (loc OpLocation) Equals(other OpLocation) bool {
122+ // Compare entire packed value (including nullified bit)
123+ return loc == other
124+}
125+126+func (loc OpLocation) PositionEquals(other OpLocation) bool {
127+ // Compare only position (ignore nullified bit)
128+ return loc.GlobalPosition() == other.GlobalPosition()
129+}
130+131+// Convenience conversions
132+func (loc OpLocation) BundleInt() int {
133+ return int(loc.Bundle())
134+}
135+136+func (loc OpLocation) PositionInt() int {
137+ return int(loc.Position())
138+}
139+140+// For sorting/comparison
141+func (loc OpLocation) Less(other OpLocation) bool {
142+ return loc.GlobalPosition() < other.GlobalPosition()
143+}