package common import "sync" func NewPagination(data []interface{}, size int) *Pagination { p := &Pagination{ data: data, lock: new(sync.RWMutex), } p.SetPageSize(size) return p } type Pagination struct { data []interface{} currentPage int pageSize int totalPage int lock *sync.RWMutex } func (p *Pagination) GetNextPageData() []interface{} { if !p.HasNext() { return []interface{}{} } p.lock.Lock() p.currentPage++ p.lock.Unlock() return p.GetPageData(p.currentPage) } func (p *Pagination) GetPrevPageData() []interface{} { if !p.HasPrev() { return []interface{}{} } p.lock.Lock() p.currentPage-- p.lock.Unlock() return p.GetPageData(p.currentPage) } func (p *Pagination) GetPageData(pageIndex int) []interface{} { p.lock.RLock() defer p.lock.RUnlock() var ( endIndex int startIndex int ) endIndex = p.pageSize * pageIndex startIndex = endIndex - p.pageSize if endIndex > len(p.data) { endIndex = len(p.data) } return p.data[startIndex:endIndex] } func (p *Pagination) CurrentPage() int { p.lock.RLock() defer p.lock.RUnlock() return p.currentPage } func (p *Pagination) TotalCount() int { p.lock.RLock() defer p.lock.RUnlock() return len(p.data) } func (p *Pagination) TotalPage() int { p.lock.RLock() defer p.lock.RUnlock() return p.totalPage } func (p *Pagination) SetPageSize(size int) { if size <= 0 { panic("Pagination size should be larger than zero") } p.lock.Lock() defer p.lock.Unlock() if p.pageSize == size { return } p.pageSize = size if len(p.data)%size == 0 { p.totalPage = len(p.data) / size } else { p.totalPage = len(p.data)/size + 1 } p.currentPage = 1 } func (p *Pagination) PageSize() int { p.lock.RLock() defer p.lock.RUnlock() return p.pageSize } func (p *Pagination) HasNext() bool { p.lock.RLock() defer p.lock.RUnlock() return p.currentPage < p.totalPage } func (p *Pagination) HasPrev() bool { p.lock.RLock() defer p.lock.RUnlock() return p.currentPage > 1 }