Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

strips.gno

3.92 Kb · 169 lines
  1package kourtv3
  2import bptree "gno.land/p/nt/bptree/v0"
  3const stripActorCap = 5
  4type stripRow struct {
  5	slug    string
  6	claimID uint64
  7}
  8var globalStripIdx = bptree.NewBPTree32()
  9func beHeightKey(h int64) string {
 10	if h < 0 {
 11		h = 0
 12	}
 13	return beClaimKey(uint64(h))
 14}
 15func stripDeadline(cs *claimState) int64 { return cs.answerHeight + settleDelay }
 16func stripKey(cs *claimState) string {
 17	return beHeightKey(stripDeadline(cs)) + beClaimKey(cs.id)
 18}
 19func globalStripKey(slug string, cs *claimState) string {
 20	return beHeightKey(stripDeadline(cs)) + slug + beClaimKey(cs.id)
 21}
 22func pendingKey(cs *claimState) string {
 23	return beHeightKey(cs.openedAt) + beClaimKey(cs.id)
 24}
 25func stripEnter(c *Court, cs *claimState) {
 26	if cs.inStrip {
 27		return
 28	}
 29	if c.stripIdx == nil {
 30		c.stripIdx = bptree.NewBPTree32()
 31	}
 32	c.stripIdx.Set(stripKey(cs), cs.id)
 33	globalStripIdx.Set(globalStripKey(c.id, cs), &stripRow{slug: c.id, claimID: cs.id})
 34	cs.inStrip = true
 35}
 36func stripExit(c *Court, cs *claimState) {
 37	if !cs.inStrip {
 38		return
 39	}
 40	if c.stripIdx != nil {
 41		c.stripIdx.Remove(stripKey(cs))
 42	}
 43	globalStripIdx.Remove(globalStripKey(c.id, cs))
 44	cs.inStrip = false
 45}
 46func pendingEnter(c *Court, cs *claimState) {
 47	if cs.inPending {
 48		return
 49	}
 50	if c.pendingIdx == nil {
 51		c.pendingIdx = bptree.NewBPTree32()
 52	}
 53	c.pendingIdx.Set(pendingKey(cs), cs.id)
 54	cs.inPending = true
 55}
 56func pendingExit(c *Court, cs *claimState) {
 57	if !cs.inPending {
 58		return
 59	}
 60	if c.pendingIdx != nil {
 61		c.pendingIdx.Remove(pendingKey(cs))
 62	}
 63	cs.inPending = false
 64}
 65func stripPageIDs(c *Court, offset, limit int) []uint64 {
 66	out := []uint64{}
 67	if c.stripIdx == nil || limit <= 0 {
 68		return out
 69	}
 70	capBinds := c.stripIdx.Size() > renderPageSize
 71	perAnswerer := map[string]int{}
 72	perAuthor := map[string]int{}
 73	skipped := 0
 74	c.stripIdx.Iterate("", "", func(_ string, v any) bool {
 75		id, ok := v.(uint64)
 76		if !ok {
 77			return false
 78		}
 79		cv := c.claims.Get(beClaimKey(id))
 80		if cv == nil {
 81			return false
 82		}
 83		cs := cv.(*claimState)
 84		if capBinds && !cs.seeded {
 85			a := cs.answerer.String()
 86			b := cs.author.String()
 87			if perAnswerer[a] >= stripActorCap || perAuthor[b] >= stripActorCap {
 88				return false
 89			}
 90			perAnswerer[a]++
 91			perAuthor[b]++
 92		}
 93		if skipped < offset {
 94			skipped++
 95			return false
 96		}
 97		out = append(out, id)
 98		return len(out) >= limit
 99	})
100	return out
101}
102func StripPage(courtSlug string, offset, limit int) []uint64 {
103	return stripPageIDs(mustCourt(courtSlug), offset, limit)
104}
105func StripSize(courtSlug string) int {
106	c := mustCourt(courtSlug)
107	if c.stripIdx == nil {
108		return 0
109	}
110	return c.stripIdx.Size()
111}
112func PendingPage(courtSlug string, offset, limit int) []uint64 {
113	out := []uint64{}
114	c := mustCourt(courtSlug)
115	if c.pendingIdx == nil || limit <= 0 {
116		return out
117	}
118	c.pendingIdx.IterateByOffset(offset, limit, func(_ string, v any) bool {
119		if id, ok := v.(uint64); ok {
120			out = append(out, id)
121		}
122		return false
123	})
124	return out
125}
126func PendingSize(courtSlug string) int {
127	c := mustCourt(courtSlug)
128	if c.pendingIdx == nil {
129		return 0
130	}
131	return c.pendingIdx.Size()
132}
133func DirectoryStripPage(offset, limit int) ([]string, []uint64) {
134	slugs := []string{}
135	ids := []uint64{}
136	if limit <= 0 {
137		return slugs, ids
138	}
139	capBinds := globalStripIdx.Size() > renderPageSize
140	perCourt := map[string]int{}
141	skipped := 0
142	globalStripIdx.Iterate("", "", func(_ string, v any) bool {
143		r, ok := v.(*stripRow)
144		if !ok {
145			return false
146		}
147		if capBinds {
148			if perCourt[r.slug] >= stripActorCap {
149				return false
150			}
151			perCourt[r.slug]++
152		}
153		if skipped < offset {
154			skipped++
155			return false
156		}
157		slugs = append(slugs, r.slug)
158		ids = append(ids, r.claimID)
159		return len(slugs) >= limit
160	})
161	return slugs, ids
162}
163func DirectoryStripSize() int { return globalStripIdx.Size() }
164func OnStrip(courtSlug string, claimID uint64) bool {
165	return mustClaim(mustCourt(courtSlug), claimID).inStrip
166}
167func OnPending(courtSlug string, claimID uint64) bool {
168	return mustClaim(mustCourt(courtSlug), claimID).inPending
169}