Beispiel #1
0
// Location is the Location this page starts at
func (p Page) Location() Location {
	if p.Is91() {
		return LocationFromUint32s(uint32(pg.LUint(p.bs[8:12])), uint32(pg.LUint(p.bs[12:16])))
	}

	return LocationFromUint32s(uint32(pg.LUint(p.bs[12:16])), uint32(pg.LUint(p.bs[8:12])))
}
Beispiel #2
0
// Previous is the location of the record that preceeds this one
func (r RecordHeader) Previous() Location {
	switch r.version {
	case 0xD066:
		return LocationFromUint32s(uint32(pg.LUint(r.bs[4:8])), uint32(pg.LUint(r.bs[8:12])))
	case 0xD07E:
		return LocationFromUint32s(uint32(pg.LUint(r.bs[20:24])), uint32(pg.LUint(r.bs[16:20])))
	}

	return Location{}
}
Beispiel #3
0
// Crc is the crc of the record
func (r RecordHeader) Crc() uint32 {
	switch r.version {
	case 0xD066:
		return uint32(pg.LUint(r.bs[0:4]))
	case 0xD07E:
		return uint32(pg.LUint(r.bs[24:28]))
	}

	return 0
}
Beispiel #4
0
// ResourceManagerID is the ID of the resource manager that created this record
func (r RecordHeader) ResourceManagerID() uint8 {
	switch r.version {
	case 0xD066:
		return uint8(pg.LUint(r.bs[25:26]))
	case 0xD07E:
		return uint8(pg.LUint(r.bs[13:14]))
	}

	return 0
}
Beispiel #5
0
// Info contains resource manager specific data
func (r RecordHeader) Info() uint8 {
	switch r.version {
	case 0xD066:
		return uint8(pg.LUint(r.bs[24:25]))
	case 0xD07E:
		return uint8(pg.LUint(r.bs[12:13]))
	}

	return 0
}
Beispiel #6
0
// Length is the length of resource manager specific data after the header
func (r RecordHeader) Length() uint32 {
	switch r.version {
	case 0xD066:
		return uint32(pg.LUint(r.bs[20:24]))
	case 0xD07E:
		return uint32(pg.LUint(r.bs[8:12]))
	}

	return 0
}
Beispiel #7
0
// TotalLength is the length of the body after the header but before the next record
func (r RecordHeader) TotalLength() uint32 {
	switch r.version {
	case 0xD066:
		return uint32(pg.LUint(r.bs[16:20]))
	case 0xD07E:
		return uint32(pg.LUint(r.bs[0:4]))
	}

	return 0
}
Beispiel #8
0
// TransactionID is the transaction that this record is apart of
func (r RecordHeader) TransactionID() uint32 {
	switch r.version {
	case 0xD066:
		return uint32(pg.LUint(r.bs[12:16]))
	case 0xD07E:
		return uint32(pg.LUint(r.bs[4:8]))
	}

	return 0
}
Beispiel #9
0
// ToOffset is item number of the new version of this tuple
func (d UpdateData) ToOffset() uint16 {
	switch d.version {
	case 0xD066:
		return uint16(pg.LUint(d.bs[24:26]))
	case 0xD07E:
		return uint16(pg.LUint(d.bs[32:34]))
	}

	return 0
}
Beispiel #10
0
// BlockSize is the size of a page in a WAL file
func (p Page) BlockSize() uint32 {
	if p.IsLong() {
		return uint32(pg.LUint(p.bs[28:32]))
	}

	return 0
}
Beispiel #11
0
// SegmentSize is the size in bytes of a single WAL file
func (p Page) SegmentSize() uint32 {
	if p.IsLong() {
		return uint32(pg.LUint(p.bs[24:28]))
	}

	return 0
}
Beispiel #12
0
// SystemID can be used to determine if a page was written by a particular server
func (p Page) SystemID() uint64 {
	if p.IsLong() {
		return uint64(pg.LUint(p.bs[16:24]))
	}

	return 0
}
Beispiel #13
0
func parseMultiInsertData(isInit bool, d []byte) (multiInserts []HeapData) {
	const XlogHeapInitPage = 128

	var (
		tablespaceID = uint32(pg.LUint(d[0:4]))
		databaseID   = uint32(pg.LUint(d[4:8]))
		relationID   = uint32(pg.LUint(d[8:12]))
		toBlock      = uint32(pg.LUint(d[12:16]))
		flags        = d[16]
		ntuples      = uint16(pg.LUint(d[18:20]))
	)

	isInit = isInit || flags&XlogHeapInitPage > 0

	for i := uint16(0); i < ntuples; i++ {
		if isInit {
			multiInserts = append(multiInserts, MultiInsertData{tablespaceID, databaseID, relationID, toBlock, i + 1})
		} else {
			var (
				start    = i*2 + 20
				end      = start + 2
				toOffset = uint16(pg.LUint(d[start:end]))
			)

			multiInserts = append(multiInserts, MultiInsertData{tablespaceID, databaseID, relationID, toBlock, toOffset})
		}
	}

	return
}
Beispiel #14
0
// Continuation will return the bytes of a continuation of the previous record's body if present on the page
func (p Page) Continuation() []byte {
	if p.IsCont() {
		var contStart, contEnd uint64

		if p.Is94() {
			contStart = p.HeaderLength()
			contEnd = contStart + pg.LUint(p.bs[16:20])
		} else {
			sizeOffset := p.HeaderLength()
			contStart = sizeOffset + 4
			contEnd = contStart + pg.LUint(p.bs[sizeOffset:contStart])
		}

		maxContEnd := uint64(len(p.bs))
		if contEnd > maxContEnd {
			contEnd = maxContEnd
		}

		return p.bs[contStart:contEnd]
	}

	return nil
}
Beispiel #15
0
// Continuation will return the bytes of a continuation of the previous record's body if present on the page
func (p Page) Continuation() []byte {
	if p.IsCont() {
		sizeOffset := p.HeaderLength()
		contStart := sizeOffset + 4
		contEnd := contStart + uint64(pg.LUint(p.bs[sizeOffset:contStart]))

		maxContEnd := uint64(len(p.bs))
		if contEnd > maxContEnd {
			contEnd = maxContEnd
		}

		return p.bs[contStart:contEnd]
	}

	return nil
}
Beispiel #16
0
// DatabaseID is the id of the database this tuple is found in
func (d InsertData) DatabaseID() uint32 { return uint32(pg.LUint(d[4:8])) }
Beispiel #17
0
// TablespaceID is the id of the tablespace this tuple is found in
func (d InsertData) TablespaceID() uint32 { return uint32(pg.LUint(d[0:4])) }
Beispiel #18
0
func readBlockID(bs []byte) uint32 {
	return (uint32(pg.LUint(bs[0:2])) << 16) + uint32(pg.LUint(bs[2:4]))
}
Beispiel #19
0
// TimelineID is the timeline this page is found on
func (p Page) TimelineID() uint32 {
	return uint32(pg.LUint(p.bs[4:8]))
}
Beispiel #20
0
// RelationID is the id of the relation this tuple is found in
func (d UpdateData) RelationID() uint32 { return uint32(pg.LUint(d.bs[8:12])) }
Beispiel #21
0
// TablespaceID is the id of the tablespace this tuple is found in
func (d UpdateData) TablespaceID() uint32 { return uint32(pg.LUint(d.bs[0:4])) }
Beispiel #22
0
// TablespaceID is the id of the tablespace this tuple is found in
func (d DeleteData) TablespaceID() uint32 { return uint32(pg.LUint(d[0:4])) }
Beispiel #23
0
// RelationID is the id of the relation this tuple is found in
func (d InsertData) RelationID() uint32 { return uint32(pg.LUint(d[8:12])) }
Beispiel #24
0
// DatabaseID is the id of the database this tuple is found in
func (d DeleteData) DatabaseID() uint32 { return uint32(pg.LUint(d[4:8])) }
Beispiel #25
0
// ToOffset is the item number where this tuple now resides
func (d InsertData) ToOffset() uint16 { return uint16(pg.LUint(d[16:18])) }
Beispiel #26
0
// RelationID is the id of the relation this tuple is found in
func (d DeleteData) RelationID() uint32 { return uint32(pg.LUint(d[8:12])) }
Beispiel #27
0
// DatabaseID is the id of the database this tuple is found in
func (d UpdateData) DatabaseID() uint32 { return uint32(pg.LUint(d.bs[4:8])) }
Beispiel #28
0
// FromOffset is the item number where this tuple previously resided
func (d DeleteData) FromOffset() uint16 { return uint16(pg.LUint(d[16:18])) }
Beispiel #29
0
// FromOffset is the item number of the old version of this tuple
func (d UpdateData) FromOffset() uint16 { return uint16(pg.LUint(d.bs[16:18])) }
Beispiel #30
0
// Info can be used to determine if a page header is long (bit 2 is set) or if it contains a continuation (bit 1 is set)
func (p Page) Info() uint16 {
	return uint16(pg.LUint(p.bs[2:4]))
}