// Managing serialization of Pages func (self *TnyColumn) NewPage() *TnyPage { C_key_count := C.int(self.Type.KeyCount()) page := new(TnyPage) page.Column = self page.index = len(self.Pages) // Also allocate the page_data page.cptr = C.tny_page_new(C_key_count, C.int(0)) self.Pages = append(self.Pages, page) self.PageDefinitions = append(self.PageDefinitions, page.GetDefinition()) return page }
func ReadPage(reader *bufio.Reader, column *TnyColumn, def *TnyPageDefinition) *TnyPage { C_key_count := C.int(column.KeyCount()) page := new(TnyPage) page.Column = column page.dirty = false var depth, length int32 binary.Read(reader, binary.LittleEndian, &depth) binary.Read(reader, binary.LittleEndian, &length) page.cptr = C.tny_page_new(C_key_count, C.int(length)) // fmt.Printf("Reading page for %s (ptr: %p, len: %d):\n", page.Column.Name, page.cptr, page.Length()) // C_depth := C.tny_page_depth(page.cptr) // fmt.Printf("Reading page for %s (%p):\n", column.Name, page.cptr) // Allocate the page in C for d := int32(0); d < depth; d++ { // Get C to make us a Bitmap so that its aligned and not // garbage collected // Get the allocated line and make a slice pointing to it that // can be updated by the binary.Read bmp := page.BitmapAtDepth(int(d)) // We want a slice that we can pass to binary.Read, but we need // to make sure that its not going to get collected, so check this out! word_length := (PAGE_MAX_VALUES / 64) // Make a slice, then record its header bmpSlice := make([]uint64, 1) sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&bmpSlice))) // Track what it was, so we can set it back and GC can clean that up // rather than trashing my actual data o_cap := sliceHeader.Cap o_len := sliceHeader.Len o_data := sliceHeader.Data sliceHeader.Cap = (word_length) sliceHeader.Len = (word_length) sliceHeader.Data = uintptr(unsafe.Pointer(bmp.cptr)) // fmt.Printf("Pointer pre: %p\n", SlicePointer(bmpSlice)) // fmt.Printf("Reading data for depth %d...\n", d) // This should read my data straight into my C array! // Unless it doesnt work ofcourse! // Read data from the file into my C array err := binary.Read(reader, binary.LittleEndian, bmpSlice) // Now that we have read my data, reset the slice back to what it was // ready for garbage collection, keeping my C array a secret! Shhh... sliceHeader.Cap = o_cap sliceHeader.Len = o_len sliceHeader.Data = o_data // fmt.Printf("\t%s\n", bmp.BitString(100)) if err != nil { panic("Unable to read page (" + err.Error() + ")") } } def.Loaded = true // Test the first few values // fmt.Printf("Read Page (%d): ", depth) // for i := 0; i < 10; i++ { // fmt.Printf("%d, ", page.Access(i)) // } // fmt.Printf("\n") return page }