Skip to content

Commit

Permalink
cleanup Insert function, add (missing) insert unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
JesseCoretta committed Aug 8, 2023
1 parent 04ef4f1 commit cfd70ff
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 47 deletions.
98 changes: 51 additions & 47 deletions stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,81 +208,85 @@ func (r Stack) SetMessageChan(mchan chan Message) Stack {
}

/*
Insert will insert value x to the right side of the left integer,
and returns a success indicative boolean value. A value of true
indicates the receiver length became longer by one (1).
Insert will insert value x to become the left index. For example,
using zero (0) as left shall result in value x becoming the first
slice within the receiver.
This method returns a boolean value indicative of success. A value
of true indicates the receiver length became longer by one (1).
This method does not currently respond to forward/negative index
support. An integer value less than or equal to zero (0) shall
become zero (0). An integer value that exceeds the length of the
receiver shall become index len-1. A value that falls within the
bounds of the receiver's current length is inserted as intended.
*/
func (r Stack) Insert(x any, left int) (ok bool) {
return r.stack.insert(x, left)
}

/*
insert is a private method called by Stack.Insert.
TODO: clean this monstrosity up.
*/
func (r *stack) insert(x any, left int) (ok bool) {
// bail out if receiver is nil
if x == nil {
return false
return
}

r.lock()
defer r.unlock()
// note the len before we start
var u1 int = r.ulen()

_, index, found := r.index(left)
if !found {
// bail out if a capacity has been set and
// would be breached by this insertion.
if u1+1 > r.cap() && r.cap() != 0 {
return
}

fname := uc(fmname())
r.lock()
defer r.unlock()

// note the len before we start
var u1 int = r.ulen()
cfg, _ := r.config()

// If left was the final index; just do
// a push and then verify before return.
if index > u1 {
r.wrmsg(sprintf("%s: adding new slice [%d]", fname, r.len()+1))
// If left is greater-than-or-equal
// to the user length, just push.
if u1-1 < left {
*r = append(*r, x)
ok = u1+1 == r.ulen()
r.wrmsg(sprintf("%s: updated: %t", fname, ok))

return
} else if index <= 2 {
r.wrmsg(sprintf("%s: allocation", fname))
var R stack = make(stack, 0)
R = append(R, cfg)
r.wrmsg(sprintf("%s: migrating index 1", fname))
R = append(R, (*r)[1]) // just add the second (2nd) slice
r.wrmsg(sprintf("%s: adding new slice [2]", fname))
R = append(R, x) // add the new item
r.wrmsg(sprintf("%s: migrating indices 2 through %d", fname, r.len()))
R = append(R, (*r)[2:]...) // add everything from third (3rd) slice onwards
r.wrmsg(sprintf("%s: updating %T PTR ref", fname, r))
*r = R
// Verify something was added
ok = u1+1 == r.ulen()
r.wrmsg(sprintf("%s: updated: %t", fname, ok))

return
}

var R stack = make(stack, 0)
r.wrmsg(sprintf("%s: allocation", fname))
R = append(R, cfg)
r.wrmsg(sprintf("%s: migrating indices 1 through %d", fname, index))
R = append(R, (*r)[1:index]...) // take everything from first (1st) slice -> index
r.wrmsg(sprintf("%s: adding new slice [%d]", fname, index+1))
R = append(R, x) // add the new item
r.wrmsg(sprintf("%s: migrating indices %d through %d", fname, index, r.len()))
R = append(R, (*r)[index:]...) // add everything from index onwards
r.wrmsg(sprintf("%s: updating %T PTR ref", fname, r))
*r = R
left += 1

// If left is less-than-or-equal to
// zero (0), we'll use a new stack
// alloc (R) and move items into it
// in the appropriate order. The
// new element will be the first
// user slice.
if left <= 1 {
left = 1
R = append(R, cfg)
R = append(R, x)
R = append(R, (*r)[left:]...)

// If left falls within the user length,
// append all elements up to and NOT
// including the desired index, and also
// append everything after desired index.
// This leaves a slot into which we can
// drop the new element (x)
} else {
R = append((*r)[:left+1], (*r)[left:]...)
R[left] = x
}

// make sure we succeeded both in non-nilness
// and in the expected integer length change.
// Verify something was added
*r = R
ok = u1+1 == r.ulen()
r.wrmsg(sprintf("%s: updated: %t", fname, ok))

return
}
Expand Down
27 changes: 27 additions & 0 deletions stack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,33 @@ func TestStack_And001(t *testing.T) {
}
}

func TestStack_Insert(t *testing.T) {
got := And().Paren().Fold().Push(
`testing1`,
`testing2`,
`testing3`,
)

got.Insert(`testing0`, 0)

want := `( testing0 AND testing1 AND testing2 AND testing3 )`
if got.String() != want {
t.Errorf("%s.1 failed: want '%s', got '%s'", t.Name(), want, got)
}

got.Insert(`testing2.5`, 3)
want = `( testing0 AND testing1 AND testing2 AND testing2.5 AND testing3 )`
if got.String() != want {
t.Errorf("%s.2 failed: want '%s', got '%s'", t.Name(), want, got)
}

got.Insert(`testing4`, 15)
want = `( testing0 AND testing1 AND testing2 AND testing2.5 AND testing3 AND testing4 )`
if got.String() != want {
t.Errorf("%s.3 failed: want '%s', got '%s'", t.Name(), want, got)
}
}

func TestStack_IsParen(t *testing.T) {
stk := And().Paren().Fold().Push(
`testing1`,
Expand Down

0 comments on commit cfd70ff

Please sign in to comment.