func (s *Store) getOrCreateTypedKey(k Key, v Value, kt KeyType) *BRecord { br, err := s.getKey(k, nil) if err == ENOKEY { if *GStore { thing, ok := s.gstore.Get(gotomic.Key(k)) if !ok { br = MakeBR(k, v, kt) did := s.gstore.PutIfMissing(gotomic.Key(k), unsafe.Pointer(br)) if !did { thing, ok = s.gstore.Get(gotomic.Key(k)) if !ok { log.Fatalf("Cannot put new key, but Get() says it isn't there %v\n", k) } } } br = (*BRecord)(thing) } else { if !*UseRLocks { log.Fatalf("Should have preallocated keys if not locking chunks\n") } // Create key chunk := s.store[k[0]] var ok bool chunk.Lock() br, ok = chunk.rows[k] if !ok { br = MakeBR(k, v, kt) chunk.rows[k] = br } chunk.Unlock() } } return br }
func (s *Store) getKey(k Key, ld *gotomic.LocalData) (*BRecord, error) { if len(k) == 0 { debug.PrintStack() log.Fatalf("[store] getKey(): Empty key\n") } if *GStore { var x unsafe.Pointer var ok bool hc, present := s.hash_codes[k] if ld == nil { x, ok = s.gstore.Get(gotomic.Key(k)) } else if !present { x, ok = s.gstore.GetHC(gotomic.Key(k).HashCode(), gotomic.Key(k), ld) } else { x, ok = s.gstore.GetHC(hc, gotomic.Key(k), ld) } if !ok { dlog.Printf("Not in hash map. %v %v %v\n", k, x, ok) return nil, ENOKEY } else { if x == nil { fmt.Printf("Nil brecord! %v\n", k) } return (*BRecord)(x), nil } } if !*UseRLocks { x, err := s.getKeyStatic(k) return x, err } chunk := s.store[k[0]] if chunk == nil { log.Fatalf("[store] Didn't initialize chunk for key %v byte %v\n", k, k[0]) } chunk.RLock() vr, ok := chunk.rows[k] if !ok || vr == nil { chunk.RUnlock() return vr, ENOKEY } chunk.RUnlock() return vr, nil }
func (s *Store) CreateKey(k Key, v Value, kt KeyType) *BRecord { br := MakeBR(k, v, kt) if *GStore { x, ok := s.gstore.Put(gotomic.Key(k), unsafe.Pointer(br)) if ok { fmt.Printf("Overwrote %v; already there? %v\n", k, x) } s.PrecomputeHashCode(k) } else { chunk := s.store[k[0]] chunk.Lock() chunk.rows[k] = br chunk.Unlock() } return br }
func (s *Store) CreateMuRLockedKey(k Key, kt KeyType) (*BRecord, error) { br := MakeBR(k, nil, kt) br.SRLock() if *GStore { ok := s.gstore.PutIfMissing(gotomic.Key(k), unsafe.Pointer(br)) if !ok { dlog.Printf("Key already exists %v\n", k) return nil, EEXISTS } } else { chunk := s.store[k[0]] chunk.Lock() _, ok := chunk.rows[k] if ok { chunk.Unlock() dlog.Printf("Key already exists %v\n", k) return nil, EEXISTS } chunk.rows[k] = br chunk.Unlock() } return br, nil }
func (s *Store) PrecomputeHashCode(k Key) { s.mu.Lock() s.hash_codes[k] = gotomic.Key(k).HashCode() s.mu.Unlock() }